- k8s是谷歌在2014年开源的容器化集群管理系统
- 使用k8s进行容器化应用部署
- 使用k8s利于应用扩展
- k8s目标实施让容器化应用程序更加简洁高效
(1)自动装箱
(2)自我修复(自愈能力)
(3)水平扩展
(3)服务发现
(4)滚动更新
(5)版本回退
(6)密钥和配置管理
(7)存储编排
(8)批处理
k8s 集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求; Master Node 由
API Server:集群统一入口,以restfull方式交给etcd存储
Scheduler:节点调度,选择node节点应用部署
ClusterState Store(ETCD 数据库): 存储系统,用于保存集群数据
Controller MangerServer :处理集群中常规后台任务,一个资源对应一个控制器
集群工作节点,运行用户业务应用容器; Worker Node 包含
kubelet:master派到node节点的代表,管理本机容器如生命周期,容器的创建,容器的各种操作。
kube proxy :提供网络代理,可以实现负载均衡等
和 ContainerRuntime;
- 部署的最小单元
- 一组容器的集合
- 共享网络
- 生命周期是短暂的
- 确保pod中预期的副本数量
- 无状态应用部署
- 有状态应用部署
- 确保所有的node都运行同一个pod
- 一次性任务和定时任务
ReplicaSet:确保预期的Pod副本数量 Deployment:无状态应用(例如:web、nignx、apache、tomcat) StatefulSet:有状态应用部署(例如:mysql) 有状态:该应用独一无二,无法重新创建进行完美替代,例如mysql、Oracle数据库 DaemonSet:确保所有的Node运行同一个Pod(把所有的Node设置为同一个命名空间) Job:一次性任务(类似linux:at) Cronjob:定时任务(类似linux:crontab)3、service
- 定义一组pod访问规则
- kubect get nodes 查看所有的节点
- kubectl get pod -n kube-system 查看是否runing状态
- kubectl create deployment nginx --image=nginx 创建一个pod
- kubectl get pod 查看是否runing状态
- kubectl expose deployment nginx --port=80 --type=NodePort 暴露端口
- kubectl get pod,svc 查看pod
- kubectl get cs 检查状态
- kubectl apply -f a.yaml 部署yaml文件
- kubectl get csr 查看申请
- kubectl logs --tail=200 --all-containers=true -f -n sip -lapp=contractmg
- kubectl get pods -o wide 可以看到pod的ip等完整信息
kubectl get deploy 查看部署的资源
目前生产部署 Kubernetes 集群主要有两种方式:
- (1)kubeadm Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部 署 Kubernetes 集群。 官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
- (2)二进制包 从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。 Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可 控,推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很 多工作原理,也利于后期维护。
kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具,这个工具能通 过两条指令完成一个 kubernetes 集群的部署: 第一、创建一个 Master 节点 kubeadm init 第二, 将 Node 节点加入到当前集群中 $ kubeadm join
在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:
- 一台或多台机器,操作系统 CentOS7.x-86_x64
- 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多
- 集群中所有机器之间网络互通 - 可以访问外网,需要拉取镜像
- 禁止 swap 分区
- (1) 在所有节点上安装 Docker 和 kubeadm
- (2)部署 Kubernetes Master
- (3)部署容器网络插件
- (4)部署 Kubernetes Node,将节点加入 Kubernetes 集群中
- (5)部署 Dashboard Web 页面,可视化查看 Kubernetes 资源
角色 IP
k8smaster 192.168.163.133
k8snode1 192.168.163.134
k8snode2 192.168.163.135
$ systemctl stop firewalld $ systemctl disable firewalld6.2 关闭 selinux:
$ sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 $ setenforce 0 # 临时6.3 关闭 swap:
$ swapoff -a # 临时 $ vim /etc/fstab # 永久6.4 主机名:
$ hostnamectl set-hostname
- hostnamectl set-hostname k8smaster
- hostnamectl set-hostname k8snode1
- hostnamectl set-hostname k8snode2
$ cat >> /etc/hosts << EOF 192.168.163.133 k8smaster 192.168.163.134 k8snode1 192.168.163.135 k8snode2 EOF6.6 将桥接的 IPv4 流量传递到 iptables 的链
$ cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF $ sysctl --system # 生效6.7 时间同步
$ yum install ntpdate -y $ ntpdate time.windows.com7、所有节点安装 Docker/kubeadm/kubelet
Kubernetes 默认 CRI(容器运行时)为 Docker,因此先安装 Docker。
(1)安装 Docker$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo $ yum -y install docker-ce-18.06.1.ce-3.el7 $ systemctl enable docker && systemctl start docker $ docker --version(2)添加阿里云 YUM 软件源
设置仓库地址
# cat > /etc/docker/daemon.json << EOF
{ "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] }
EOF
添加 yum 源
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF(3)安装 kubeadm,kubelet 和 kubectl
由于版本更新频繁,这里指定版本号部署:
$ yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0 $ systemctl enable kubelet8、部署 Kubernetes Master (1)在 192.168.163.133(Master)执行
提供了一种在拉去镜像时指定镜像仓库的方法
kubeadm init --apiserver-advertise-address=192.168.163.133 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.22.3 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16
由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。
(2)使用 kubectl 工具:如果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 nodes9、安装 Pod 网络插件(CNI)
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/documentation/kube-flannel.yml
确保能够访问到 quay.io 这个 registery。如果 Pod 镜像下载失败,可以改这个镜像地址
10、加入 Kubernetes Node在 192.168.163.134/135(Node)执行
向集群添加新节点,执行在 kubeadm init 输出的 kubeadm join 命令:
$ kubeadm join 192.168.31.61:6443 --token esce21.q6hetwm8si29qxwn --discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c511、测试 kubernetes 集群
在 Kubernetes 集群中创建一个 pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx $ kubectl expose deployment nginx --port=80 --type=NodePort $ kubectl get pod,svc
访问地址:http://NodeIP:Port。比如这里访问的http://192.168.163.134:30521
2、基于二进制包安装k8s 三、k8s核心概念 1、kubernetes 集群命令行工具 kubectl 1、kubectl 概述kubectl 是 Kubernetes 集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能 够在集群上进行容器化应用的安装部署。
2、kubectl 命令的语法- comand:指定要对资源执行的操作,例如 create、get、describe 和 delete
- TYPE:指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的 形式。例如:
- NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源, 例如:
- flags:指定可选的参数。例如,可用-s 或者–server 参数指定 Kubernetes API server 的地址和端口。
k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也 就是可以把需要对资源对象操作编辑到 YAML 格式文件中,我们把这种文件叫做资源清单文 件,通过 kubectl 命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署 了。
2、YAML 文件书写格式(1)YAML 介绍 YAML :仍是一种标记语言。为了强调这种语言以数据做为中心,而不是以标记语言为重点。 YAML 是一个可读性高,用来表达数据序列的格式。
(2)YAML 基本语法
- 使用空格做为缩进
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- 低版本缩进时不允许使用 Tab 键,只允许使用空格
- 使用#标识注释,从这个字符一直到行尾,都会被解释器忽略
(3)YAML 支持的数据结构
- 对象
键值对的集合,又称为映射(mapping) / 哈希(hashes) / 字典(dictionary)
- 数组
一组按次序排列的值,又称为序列(sequence) / 列表 (list)
- 纯量(scalars)
单个的、不可再分的值
- (1)在 k8s 中,一般使用 YAML 格式的文件来创建符合我们预期期望的 pod,这样的 YAML 文件称为资源清单。
- (2)常用字段
必须存在的属性
spec 主要对象
额外的参数
适合还没有部署的资源
将创建的过程写入my1.yaml
如果写错deployment就会报unknown flags --image 有坑
kubectl create demployment web --image=nginx -o yaml --dry-run > my1.yaml2、kubectl get
适合已经部署过的资源,从已经有的导出成yaml编排清单
kubectl get deploy nginx -o=yaml --export > my2.yaml3 、pod 1、Pod 概述
Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最 小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支 撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成 Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause 容器。Pause 容器对应的镜 像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器
- (1) 最小的部署单元
- (2)包含多个容器(一组容器的集合)
- (3)一个pod容器共享网络命名空间
- (4)pod是短暂的
- (1)创建容器使用docker,一个docker对应一个容器,一个容器一个进程,是单进程设计,一个容器运行一个应用
- (2)pod是多线程设计,运行多个应用程序,一个pod有多个容器,是容器的集合体
- (3)pod是为了亲密性应用,两个应用之间交互, 网络之间调用,两个容器需要频繁调用
- (1)共享网络
通过pause容器,把其他业务容器加入到pause容器里面,让所有的业务容器在一个名称空间中,可以实现网络共享 - (2)共享存储
引入数据卷概念volumn,使用数据卷进行持久化存储
一个 Pod 里的多个容器可以***共享存储和网络***,可以看作一个逻辑的主机。共享的如 namespace,cgroups 或者其他的隔离资源。 多个容器共享同一 network namespace,由此在一个 Pod 里的多个容器共享 Pod 的 IP 和 端口 namespace,所以一个 Pod 内的多个容器之间可以通过 localhost 来进行通信,所需要 注意的是不同容器要注意不要有端口冲突即可。不同的 Pod 有不同的 IP,不同 Pod 内的多 个容器之前通信,不可以使用 IPC(如果没有特殊指定的话)通信,通常情况下使用 Pod 的 IP 进行通信。 一个 Pod 里的多个容器可以**共享存储卷**,这个存储卷会被定义为 Pod 的一部分,并且可 以挂载到该 Pod 里的所有容器的文件系统上。(2)生命周期短暂
Pod 属于生命周期比较短暂的组件,比如,当 Pod 所在节点发生故障,那么该节点上的 Pod 会被调度到其他节点,但需要注意的是,被重新调度的 Pod 是一个全新的 Pod,跟之前的 Pod 没有半毛钱关系。
(3)平坦的网络K8s 集群中的所有 Pod 都在同一个共享网络地址空间中,也就是说每个 Pod 都可以通过其 他 Pod 的 IP 地址来实现访问
5、pod镜像拉取策略
imagesPullPolicy: [ Always| Never| IfNotPresent]
获取镜像的策略,默认值为 IfNotPresent 在宿主机不存在时拉取
resources: limits: //资源限制,容器的最大可用资源数量 cpu: Srting memory: string requeste: //资源限制,容器启动的初始可用资源数量 cpu: string memory: string7、pod重启策略
restartPolicy: [ Always| Never| OnFailure]
//重启策略,默认值为 Always
如果检查失败,将杀死容器,根据pod的restartPolicy来操作
2、就绪检查 readinessProbe如果检查失败,kubernetes会把pod从service endpoints剔除
3、probe支持三种检查方法 1、httpGet发送http请求,返回200-400范围状态码为成功
2、exec执行shell命令返回状态码0位成功
3、tcpSocket发起tcp Socket建立连接
9、pod调度策略 1、创建pod的流程 2、影响调度的属性- pod的资源限制
- 节点选择器标签
spec: ndoeSelector: env_role=dev containers: - name: neginx image: nginx:1.15
对节点创建标签,master上面设置 kubectl label node node1 env_role=prod 删除节点标签:后面的-表示将该标签删除 kubectl label node node1 env_role-
- 节点亲和性
spec: affinity: nodeAffinity: requiredDruingSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchexpression: - key: env_role operator: In values: - dev - test preferredDuringSchedulingIgnoreDuringExecution: - weight: 1 preference: matchexpression: - key: group operator: In values: - otherprod containers: - name: webdemo image: nginx
节点亲和性nodeAffinity和之前的nodeSelector基本一样,根据节点上标签约束来决定pod调度到哪个节点上,
硬亲和性:约束条件必须满足
软亲和性:尝试满足,不保证
支持的常用操作符:
In NotIn Exists Gt Lt DoesNotExists
- 污点和污点容忍性
污点是节点属性,不是pod属性,不做普通的分配调度,
使用场景比如专用节点,配置特点硬件节点,基于Taint驱逐
污点的三个值:
NoSchedule:一定不会被调度
PreferSchedule : 尽量不被调度
NoExecute:不会被调度,并且还会驱逐Nde已有的pod
(1)为节点添加污点 kubectl taint node [node] key=value:污点三个值 (2)删除污点 例如: kubectl taint node k8snode1 key:NoSchedule-
污点容忍:就是配置内容
spec: tolerations: - kye: "key" operator: "Equal" value: "value" effect: "NoSchedule"4 、Conttroller
在集群上管理和运行容器的对象
2、Pod和Controller的关系Pod是通过Controller实现应用的运维,比如弹性伸缩,滚动升级等
3、Pod和Controller是通过label建立关系的 4、deployment应用场景- 部署无状态应用
- 管理pod和ReplicaSet
- 部署,滚动升级等功能
- 应用场景:web服务,微服务
kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml2、使用yaml部署应用
kubectl apply -f web.yaml3、对外发布(暴露对外端口号)
kubectl expose deployment web --port=80 --type=NodePort --traget-port=80 --name=web1 -o yaml > web1.yaml4、查看应用运行状态
kubectl get pod,svc6、deployment升级回滚和弹性伸缩 1、升级应用deployment 类型的controller nginx版本为1.15
kubectl set image deployment web nginx=nginx:1.152、查看升级的状态
kubectl rollout status deployment web3、查看升级的历史版本
kubectl rollout history deployment web4、回滚版本 1、回滚到上一个版本
kubectl rollout undo deployment web2、回滚到指定版本
kubectl rollout undo deployment web --to-revision=25、弹性伸缩
kubectl scale deployment web --replicas=55、Service 1、存在的意义
- 1、防止pod失联(服务发现)
- 2、定义一组pod的访问规则(负载均衡)
*
根据label和selector标签建立关联的
- ClusterIP 默认,集群内部使用
- NodePort 对外访问应用使用
- LoadBalancer 对外访问应用使用,公有云
node内网部署应用,外网一般不能访问到,
方法:
1 找到一台可以进行外网访问机器,安装nginx,反向代理,手动把可以访问的节点添加上
2 loadBalancer公有云,把负载均衡,控制器
4、无状态,有状态部署(1) 无状态:
认为pod都是一样的 ,使用kubectl get pods -o wide 查看pod的ip地址,ip是不一样的,每个pod内统一用一个ip
没有顺序要求
不用考虑哪个node运行
随意伸缩和扩展
(2)有状态
上面因素都需要考虑
让每个pod独立 ,保持pod启动顺序和唯一性
(唯一性网络标识符,持久存储
有序,比如mysql主从)
deployment和satefullSet区别:有身份(唯一标识),根据主机名+按照一定规则生成域名
域名规则:
主机名称.service名称.名称空间.svc.cluster.local
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
6、部署守护进程,确保所有node在一个pod运行,DamonSet
在每个node上运行一个pod,新加入的node也同时运行在一个pod里面
例子:
为每个mode节点安装数据采集工具
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
2、部署
kubectl apply -f job.yaml3、删除:job 8、定时任务 1、cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: onFailure
2、部署
kubectl apply -f cronjob.yaml3、查看
kubectl get pods -o wide4、查看日志
kubectl logs 容器名称5、删除
kubectl delete -f cronjob.yaml6、secret
加密: echo -n ‘admin’ | base64
解密:echo -n ‘fewfewf’ | base64 -d
作用:加密数据存储在etcd里面,让pod容器以挂载volmn方式进行访问
场景:凭证
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm2、以变量形式挂载到pod中
secret-var.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
secret-vol.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
部署应用:记得删除之前的变量的形式,因为都叫mypod名称的,会报错部署的时候
kubectl apply -f kubectl-vol.yaml
检查是否挂载上
作用:存储不加密数据到etcd,让pod以变量或者volumn挂载到容器中
场景:配置文件
redis.properties
redis.host=127.0.0.1 redis.port=6379 redis.password=1234562、创建configMap
kubectl create configmap redis-config --from-file=redis.properties
创建pod,挂载volumn
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: redis-config
restartPolicy: Never
(1)创建yaml,声明变量信息configMap创建
(2)以变量挂载pod
vi mycm.yaml
apiVersion: v1 kind: ConfigMap metadata: name: myconfig namespace: default data: special.level: info special.type: hello
创建pod:(config-var.yaml)
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: busybox
image: busybox
command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE)" ]
env:
- name: LEVEL
valueFrom:
configMapKeyRef:
name: myconfig
key: special.level
- name: TYPE
valueFrom:
configMapKeyRef:
name: myconfig
key: special.type
restartPolicy: Never
部署pod并将变量挂载到pod上
kubectl apply -f config-var.yaml
访问k8s集群时候,需要经过三个步骤完成具体操作:认证,授权,准入控制
进行访问的时候,过程中都需要经过apiserver,apiserver作为统一协调,比如门卫
访问过程中需要证书,token,或者用户名密码,如果访问pod,需要serviceAccount
传输安全:对外不暴露8080端口,只能内部访问,对外使用端口6443
- 认证:客户端身份常用方式
- https证书认证,基于CA证书
- http token 认证通过token识别用户
- http基本认证,用户名+密码
基于RBAC进行鉴权操作
基于角色访问控制
就是准入控制器的列表,如果列表里有请求内容,通过,没有就拒绝
5、RBAC:基于角色的访问控制角色:
role:特定命名空间访问权限
clusterRole:所有命名空间访问权限
角色绑定
roleBinding:角色绑定到主体
ClusterRoleBinding:集群角色绑定到主体
主体:
user:用户
group:用户组
serviceAccount:服务账号
kubectl create ns roletest2、查看命名空间
kubectl get ns3、在新创建的命名空间创建pod
-- 运行pod kubectl run nginx --image=nginx -n roletest -- 查看创建的pod kubect get pods -n roletest4、创建角色
rbac-role.yaml
kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: roletest name: pod-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"]
部署yaml文件创建角色:
kubectl apply -f rbac-role.yaml
查看创建的角色
kubectl get role -n roletest5、创建角色绑定
rbac-rolebinding.yaml
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-pods namespace: roletest subjects: - kind: User name: lucy # Name is case sensitive apiGroup: rbac.authorization.k8s.io roleRef: kind: Role #this must be Role or ClusterRole name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-rolebinding.yaml
kubect get role.rolebinding -n roletest6、使用证书识别证书
rabc-user.sh
cat > lucy-csr.json <证书复制进来ca开头的 cp /root/TLS/k8s/ca* ./
这个证书没有用,所以自己生成一个ca证书
ca-config.jsoncat>ca-config.json<< EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": ["signing", "key encipherment", "server auth", "client auth"] } } } } EOFca-csr.json
cat > ca-csr.json<< EOF { "CN": "etcd CA", "key": { "algo": "rsa", "size": 2048 }, "names": [{ "C": "CN", "L": "Beijing", "ST": "Beijing" }] } EOFcfssl gencert -initca ca-csr.json | cfssljson -bare ca -生成ca.csr,ca.pem ,ca-key.pem 三个文件
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucy即是rbac-user.sh里面的前两个命令拿出来执行了
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.31.63:6443 --kubeconfig=mary-kubeconfig kubectl config set-credentials mary --client-key=mary-key.pem --client-certificate=mary.pem --embed-certs=true --kubeconfig=mary-kubeconfig kubectl config set-context default --cluster=kubernetes --user=mary --kubeconfig=mary-kubeconfig kubectl config use-context default --kubeconfig=mary-kubeconfigkubectl get pods -n roletest9、ingress1、把端口号对外暴露,通过ip+端口号进行访问
查看pod详细部署在哪个节点上然后修改window的hosts域名映射
使用service里面的NodePort实现
2、NodePort缺陷在每个节点都会起到端口,在访问的时候通过任意节点,通过节点ip+端口号实现访问
3、Ingress和pod的关系
- 意味着每个端口只能使用一次,一个端口对应一个应用
- 实际访问中跳转到不同端口服务中都是用域名,根据不同的域名
pod和ingress通过service关联的,ingress作为统一的入口,由service关联一组pod
4、ingress工作流程5、使用ingress
ongoing第一步 部署ingress Controller
6、使用ingress对外暴露应用
第二步 创建ingress规则
我们这里选择官方维护nginx控制器,实现部署
- 创建nginx应用,对外暴露端口使用NodePort
kubect create deployment web --image=nginx kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
- 部署ingress Controller
ingress-controller.yamlapiVersion: v1 kind: Namespace metadata: name: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: nginx-configuration namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: tcp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- kind: ConfigMap apiVersion: v1 metadata: name: udp-services namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: v1 kind: ServiceAccount metadata: name: nginx-ingress-serviceaccount namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: nginx-ingress-clusterrole labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - endpoints - nodes - pods - secrets verbs: - list - watch - apiGroups: - "" resources: - nodes verbs: - get - apiGroups: - "" resources: - services verbs: - get - list - watch - apiGroups: - "" resources: - events verbs: - create - patch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses verbs: - get - list - watch - apiGroups: - "extensions" - "networking.k8s.io" resources: - ingresses/status verbs: - update --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: nginx-ingress-role namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx rules: - apiGroups: - "" resources: - configmaps - pods - secrets - namespaces verbs: - get - apiGroups: - "" resources: - configmaps resourceNames: # Defaults to "- " # Here: " - " # This has to be adapted if you change either parameter # when launching the nginx-ingress-controller. - "ingress-controller-leader-nginx" verbs: - get - update - apiGroups: - "" resources: - configmaps verbs: - create - apiGroups: - "" resources: - endpoints verbs: - get --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: nginx-ingress-role-nisa-binding namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: nginx-ingress-role subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: nginx-ingress-clusterrole-nisa-binding labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: nginx-ingress-clusterrole subjects: - kind: ServiceAccount name: nginx-ingress-serviceaccount namespace: ingress-nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx annotations: prometheus.io/port: "10254" prometheus.io/scrape: "true" spec: hostNetwork: true # wait up to five minutes for the drain of connections terminationGracePeriodSeconds: 300 serviceAccountName: nginx-ingress-serviceaccount nodeSelector: kubernetes.io/os: linux containers: - name: nginx-ingress-controller image: lizhenliang/nginx-ingress-controller:0.30.0 args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-configuration - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - --publish-service=$(POD_NAMESPACE)/ingress-nginx - --annotations-prefix=nginx.ingress.kubernetes.io securityContext: allowPrivilegeEscalation: true capabilities: drop: - ALL add: - NET_BIND_SERVICE # www-data -> 101 runAsUser: 101 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 protocol: TCP - name: https containerPort: 443 protocol: TCP livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 readinessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 10 lifecycle: preStop: exec: command: - /wait-shutdown --- apiVersion: v1 kind: LimitRange metadata: name: ingress-nginx namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx spec: limits: - min: memory: 90Mi cpu: 100m type: Container kubectl apply -f ingress-controller.yaml
- 查询ingress状态
kubectl get pods -n ingress-nginx
- 创建ingress规则
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: example-ingress spec: rules: - host: example.ingredemo.com http: paths: - path: / backend: serviceName: web servicePort: 80ingress01.yaml
--- # http apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: example-ingress spec: rules: - host: example.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 80ingress02.yaml
--- # https apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - sslexample.ctnrs.com secretName: secret-tls rules: - host: sslexample.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 8010、Helm 1、helm的引入
- 在window系统hosts文件中添加域名访问规则
hosts地址:C:WindowsSystem32driversetc
之前方式部署应用的基本过程
2、使用helm可以解决哪些问题
- 编写yaml文件(deployment,service,ingress)
- 如果使用之前方式部署单一应用,少数服务的应用,比较合适
- 比如微服务项目,可能有几十个服务,每个服务都有yaml文件。需要维护大量的yaml,版本管理特别不合适。
3、helm介绍
- 使用heml可以把这些yaml作为一个整体管理
- 实现yaml高效复用
- 使用helm应用级别的版本管理
helm是一个Kubernetes包管理工具,就想linux包管理器,如yum、apt,可以很方便将之前打包好的yaml文件部署到kubernetes上
4 、Helm的三个重要概念5、helm在2019年发布V3版本,和之前版本相比有变化
- Helm 是一个命令行客户端工具
- Chart 把yaml打包,是yaml的集合
- Release 基于Chart部署实体,应用级别的版本管理
6、helm安装(V3版本以后)
- V3版本删除Tiller架构变化
- release可以在不同命名空间重用
- 将Chart推送到docker仓库中
下载helm安装压缩文件,上传到linux,解压helm压缩文件,把解压后helm目录复制到/usr/bin目录下
1、配置helm仓库 1、添加仓库helm repo add 仓库名称 仓库地址 比如 helm repo add stable http://mirror.azure.cn/kubernetes/charts/2、查看仓库地址helm repo list3、删除仓库kubectl repo remove aliyun4、更新仓库地址helm repo update7、使用helm快速部署应用 1、搜索weave应用helm search repo weave2、安装weave应用helm install ui stable/weave-scope3、查看安装列表helm list4、查看安装状态helm status ui8、如何自己创建chart 1、使用命令创建chart2、在templates文件夹创建两个yaml文件
nginxchart.yaml
kubectl create deployment nginxchart --image=nginx -o yaml --dry-run >nginxchartweb.yamlnginxchartsvc.yaml
kubectl expose deployment nginxchart --port=80 --target-port=80 --name=nginxhcart --type=NodePort -o yaml --dry-run >nginxchartsvc.yaml进入templates目录,并删除生成的文件
3、安装mychart
helm install nginxchart mychart/4、应用升级helm upgrade ngingxchart mychart/9、实现yaml高效复用通过传递参数,动态渲染模板,yaml内容动态传入参数生成
1、values.yaml定义变量在chart有values.yaml文件,定义yaml文件局变量
deployment.yaml文件替换变量
service.yaml 替换变量
2、在templates的yaml文件使用values.yaml定义的变量 3、可以检查变量替换是否成功 --dry-run 10、持久化存储nfs 1、nfs网络存储 pod重启数据化存在
第一步找一台服务器nfs服务器
安装nfsyum install -y nfs-utils设置挂载路径
vi /etc/exports 添加/data/nfs *(rw,no_root_squash) 挂载路径需要创建出来 /data/nfs第二步:在k8s集群node节点安装nfs: yum install -y nfs-utils
第三步:在nfs服务器启动nfs服务system start nfs 查看 ps -ef | grep nfs第四步:在k8s集群部署应用使用nfs持久网络存储
kubectl apply -f nfs-nginx.yaml kubectl exec -it nginx-dept1-xxx bashapiVersion: apps/v1 kind: Deployment metadata: name: nginx-dep1 spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx volumeMounts: - name: wwwroot mountPath: /usr/share/nginx/html ports: - containerPort: 80 volumes: - name: wwwroot nfs: server: 192.168.63.133 path: /data/nfs2、PV和PVC
暴露端口后使用ip访问首页
pv.yamlapiVersion: v1 kind: PersistentVolume metadata: name: my-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteMany nfs: path: /k8s/nfs server: 192.168.63.163pvc.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-dep1 spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx volumeMounts: - name: wwwroot mountPath: /usr/share/nginx/html ports: - containerPort: 80 volumes: - name: wwwroot persistentVolumeClaim: claimName: my-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi四、搭建集群监控平台系统 1、监控指标集群监控:资源资源利用率,节点数,运行pods
2、监控平台搭建方案 prometheus+Grafana接入即可
pod监控:容器指标,应用指标prometheus:开源的,监控报警,数据库,以http协议周期性抓取被监控组件状态,不需要复杂的集成过程,使用http接口即可
1、node-exporter.yaml 守护进程
grafana:开源的数据分析和可视化工具,支持多种数据源
--- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter namespace: kube-system labels: k8s-app: node-exporter spec: selector: matchLabels: k8s-app: node-exporter template: metadata: labels: k8s-app: node-exporter spec: containers: - image: prom/node-exporter name: node-exporter ports: - containerPort: 9100 protocol: TCP name: http --- apiVersion: v1 kind: Service metadata: labels: k8s-app: node-exporter name: node-exporter namespace: kube-system spec: ports: - name: http port: 9100 nodePort: 31672 protocol: TCP type: NodePort selector: k8s-app: node-exporter2、prometheus 1、rbac-setup.yamlapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: [""] resources: - nodes - nodes/proxy - services - endpoints - pods verbs: ["get", "list", "watch"] - apiGroups: - extensions resources: - ingresses verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] --- apiVersion: v1 kind: ServiceAccount metadata: name: prometheus namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: prometheus namespace: kube-system2、configmap.yamlapiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: kube-system data: prometheus.yml: | global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'kubernetes-apiservers' kubernetes_sd_configs: - role: endpoints scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] action: keep regex: default;kubernetes;https - job_name: 'kubernetes-nodes' kubernetes_sd_configs: - role: node scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: [__meta_kubernetes_node_name] regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics - job_name: 'kubernetes-cadvisor' kubernetes_sd_configs: - role: node scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token relabel_configs: - action: labelmap regex: __meta_kubernetes_node_label_(.+) - target_label: __address__ replacement: kubernetes.default.svc:443 - source_labels: [__meta_kubernetes_node_name] regex: (.+) target_label: __metrics_path__ replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor - job_name: 'kubernetes-service-endpoints' kubernetes_sd_configs: - role: endpoints relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] action: replace target_label: __scheme__ regex: (https?) - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] action: replace target_label: __address__ regex: ([^:]+)(?::d+)?;(d+) replacement: $1:$2 - action: labelmap regex: __meta_kubernetes_service_label_(.+) - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_service_name] action: replace target_label: kubernetes_name - job_name: 'kubernetes-services' kubernetes_sd_configs: - role: service metrics_path: /probe params: module: [http_2xx] relabel_configs: - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] action: keep regex: true - source_labels: [__address__] target_label: __param_target - target_label: __address__ replacement: blackbox-exporter.example.com:9115 - source_labels: [__param_target] target_label: instance - action: labelmap regex: __meta_kubernetes_service_label_(.+) - source_labels: [__meta_kubernetes_namespace] target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_service_name] target_label: kubernetes_name - job_name: 'kubernetes-ingresses' kubernetes_sd_configs: - role: ingress relabel_configs: - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe] action: keep regex: true - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path] regex: (.+);(.+);(.+) replacement: ${1}://${2}${3} target_label: __param_target - target_label: __address__ replacement: blackbox-exporter.example.com:9115 - source_labels: [__param_target] target_label: instance - action: labelmap regex: __meta_kubernetes_ingress_label_(.+) - source_labels: [__meta_kubernetes_namespace] target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_ingress_name] target_label: kubernetes_name - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] action: replace regex: ([^:]+)(?::d+)?;(d+) replacement: $1:$2 target_label: __address__ - action: labelmap regex: __meta_kubernetes_pod_label_(.+) - source_labels: [__meta_kubernetes_namespace] action: replace target_label: kubernetes_namespace - source_labels: [__meta_kubernetes_pod_name] action: replace target_label: kubernetes_pod_name3、prometheus.deploy.yml--- apiVersion: apps/v1 kind: Deployment metadata: labels: name: prometheus-deployment name: prometheus namespace: kube-system spec: replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: containers: - image: prom/prometheus:v2.0.0 name: prometheus command: - "/bin/prometheus" args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" - "--storage.tsdb.retention=24h" ports: - containerPort: 9090 protocol: TCP volumeMounts: - mountPath: "/prometheus" name: data - mountPath: "/etc/prometheus" name: config-volume resources: requests: cpu: 100m memory: 100Mi limits: cpu: 500m memory: 2500Mi serviceAccountName: prometheus volumes: - name: data emptyDir: {} - name: config-volume configMap: name: prometheus-config4、prometheus.svc.yml--- kind: Service apiVersion: v1 metadata: labels: app: prometheus name: prometheus namespace: kube-system spec: type: NodePort ports: - port: 9090 targetPort: 9090 nodePort: 30003 selector: app: prometheus3、grafana 1、grafana-deploy.yamlapiVersion: apps/v1 kind: Deployment metadata: name: grafana-core namespace: kube-system labels: app: grafana component: core spec: selector: matchLabels: app: grafana component: core replicas: 1 template: metadata: labels: app: grafana component: core spec: containers: - image: grafana/grafana:4.2.0 name: grafana-core imagePullPolicy: IfNotPresent # env: resources: # keep request = limit to keep this container in guaranteed class limits: cpu: 100m memory: 100Mi requests: cpu: 100m memory: 100Mi env: # The following env variables set up basic auth twith the default admin user and admin password. - name: GF_AUTH_BASIC_ENABLED value: "true" - name: GF_AUTH_ANONYMOUS_ENABLED value: "false" # - name: GF_AUTH_ANONYMOUS_ORG_ROLE # value: Admin # does not really work, because of template variables in exported dashboards: # - name: GF_DASHBOARDS_JSON_ENABLED # value: "true" readinessProbe: httpGet: path: /login port: 3000 # initialDelaySeconds: 30 # timeoutSeconds: 1 volumeMounts: - name: grafana-persistent-storage mountPath: /var volumes: - name: grafana-persistent-storage emptyDir: {}2、grafana-svc.yamlapiVersion: v1 kind: Service metadata: name: grafana namespace: kube-system labels: app: grafana component: core spec: type: NodePort ports: - port: 3000 selector: app: grafana component: core3、grafana-ing.yamlapiVersion: extensions/v1beta1 kind: Ingress metadata: name: grafana namespace: kube-system spec: rules: - host: k8s.grafana http: paths: - path: / backend: serviceName: grafana servicePort: 30003、部署prometheus先部署守护进程
kubectl create -f xxx.yaml
kubectl apply -f xxx.yamlkubectl appply -f node-exporter.yaml kubectl appply -f rbac-setup.yaml kubectl appply -f configmap.yaml kubectl appply -f prometheus.deploy.yml kubectl appply -f prometheus.svc.yml4、部署grafanakubectl apply -f grafana-deploy.yaml kubectl apply -f grafana-svc.yaml kubectl apply -f grafana-ing.yaml5、打开grafana配置数据源导入显示模板315用户名密码都是admin
五、从零搭建高可用k8s集群
1、搭建高可用步骤
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。 这个工具能通过两条指令完成一个kubernetes集群的部署:创建一个 Master 节点$ kubeadm init
将一个 Node 节点加入到当前集群中$ kubeadm join
## 1. 安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: - 一台或多台机器,操作系统 CentOS7.x-86_x64 - 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多 - 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点 - 禁止swap分区 ## 2. 准备环境 | 角色 | IP | | ------------- | -------------- | | master1 | 192.168.44.155 | | master2 | 192.168.44.156 | | node1 | 192.168.44.157 | | VIP(虚拟ip) | 192.168.44.158 |关闭防火墙systemctl stop firewalld
关闭selinux
systemctl disable firewalldsed -i ‘s/enforcing/disabled/’ /etc/selinux/config # 永久
关闭swap
setenforce 0 # 临时swapoff -a # 临时
根据规划设置主机名
sed -ri ‘s/.swap./#&/’ /etc/fstab # 永久hostnamectl set-hostname
在master添加hostscat >> /etc/hosts << EOF
将桥接的IPv4流量传递到iptables的链
192.168.44.158 master.k8s.io k8s-vip
192.168.44.155 master01.k8s.io master1
192.168.44.156 master02.k8s.io master2
192.168.44.157 node01.k8s.io node1
EOFcat > /etc/sysctl.d/k8s.conf << EOF
时间同步
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效yum install ntpdate -y
ntpdate time.windows.com## 3. 所有master节点部署keepalived ### 3.1 安装相关包和keepalivedyum install -y conntrack-tools libseccomp libtool-ltdl
yum install -y keepalived
### 3.2配置master节点 master1节点配置cat > /etc/keepalived/keepalived.conf <
! Configuration File for keepalived global_defs {
router_id k8s
}vrrp_script check_haproxy {
script “killall -0 haproxy”
interval 3
weight -2
fall 10
rise 2
}vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 250
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.44.158
}
track_script {
check_haproxy
}}
EOFmaster2节点配置cat > /etc/keepalived/keepalived.conf <
! Configuration File for keepalived global_defs {
router_id k8s
}vrrp_script check_haproxy {
script “killall -0 haproxy”
interval 3
weight -2
fall 10
rise 2
}vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.44.158
}
track_script {
check_haproxy
}}
EOF### 3.3 启动和检查 在两台master节点都执行启动keepalived$ systemctl start keepalived.service
查看启动状态
设置开机启动
$ systemctl enable keepalived.service$ systemctl status keepalived.service
启动后查看master1的网卡信息ip a s ens33
## 4. 部署haproxy ### 4.1 安装yum install -y haproxy
### 4.2 配置 两台master节点的配置均相同,配置中声明了后端代理的两个master节点服务器,指定了haproxy运行的端口为16443等,因此16443端口为集群的入口cat > /etc/haproxy/haproxy.cfg << EOF
Global settings
#---------------------------------------------------------------------#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
# 1) configure syslog to accept network log events. This is done
# by adding the ‘-r’ option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats#---------------------------------------------------------------------
common defaults that all the ‘listen’ and ‘backend’ sections will use if not designated in their block#---------------------------------------------------------------------
kubernetes apiserver frontend which proxys to the backends
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------#---------------------------------------------------------------------
round robin balancing between the various backends
frontend kubernetes-apiserver
mode tcp
bind *:16443
option tcplog
default_backend kubernetes-apiserver
#---------------------------------------------------------------------#---------------------------------------------------------------------
collection haproxy statistics message
backend kubernetes-apiserver
mode tcp
balance roundrobin
server master01.k8s.io 192.168.44.155:6443 check
server master02.k8s.io 192.168.44.156:6443 check
#---------------------------------------------------------------------#---------------------------------------------------------------------
listen stats
bind *:1080
stats auth admin:awesomePassword
stats refresh 5s
stats realm HAProxy Statistics
stats uri /admin?stats
EOF### 4.3 启动和检查 两台master都启动设置开机启动$ systemctl enable haproxy
开启haproxy$ systemctl start haproxy
查看启动状态$ systemctl status haproxy
检查端口netstat -lntup|grep haproxy
## 5. 所有节点安装Docker/kubeadm/kubelet Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。 ### 5.1 安装Docker$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
Docker version 18.06.1-ce, build e68fc7a$ cat > /etc/docker/daemon.json << EOF
{
“registry-mirrors”: [“https://b9pmyelo.mirror.aliyuncs.com”]
}
EOF### 5.2 添加阿里云YUM软件源$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF### 5.3 安装kubeadm,kubelet和kubectl 由于版本更新频繁,这里指定版本号部署:$ yum install -y kubelet-1.16.3 kubeadm-1.16.3 kubectl-1.16.3
$ systemctl enable kubelet## 6. 部署Kubernetes Master ### 6.1 创建kubeadm配置文件 在具有vip的master上操作,这里为master1$ mkdir /usr/local/kubernetes/manifests -p
$ cd /usr/local/kubernetes/manifests/
$ vi kubeadm-config.yaml
apiServer:
certSANs:
- master1
- master2
- master.k8s.io
- 192.168.44.158
- 192.168.44.155
- 192.168.44.156
- 127.0.0.1
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: “master.k8s.io:16443”
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.3
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.1.0.0/16
scheduler: {}### 6.2 在master1节点执行$ kubeadm init --config kubeadm-config.yaml
按照提示配置环境变量,使用kubectl工具: ```bash 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 nodes $ kubectl get pods -n kube-system按照提示保存以下内容,一会要使用:
kubeadm join master.k8s.io:16443 --token jv5z7n.3y1zi95p952y9p65 --discovery-token-ca-cert-hash sha256:403bca185c2f3a4791685013499e7ce58f9848e2213e27194b75a2e3293d8812 --control-plane查看集群状态
kubectl get cs kubectl get pods -n kube-system7.安装集群网络从官方地址获取到flannel的yaml,在master1上执行
mkdir flannel cd flannel wget -c https://raw.githubusercontent.com/coreos/flannel/master/documentation/kube-flannel.yml安装flannel网络
kubectl apply -f kube-flannel.yml检查
kubectl get pods -n kube-system8、master2节点加入集群 8.1 复制密钥及相关文件从master1复制密钥及相关文件到master2
# ssh root@192.168.44.156 mkdir -p /etc/kubernetes/pki/etcd # scp /etc/kubernetes/admin.conf root@192.168.44.156:/etc/kubernetes # scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.44.156:/etc/kubernetes/pki # scp /etc/kubernetes/pki/etcd/ca.* root@192.168.44.156:/etc/kubernetes/pki/etcd8.2 master2加入集群执行在master1上init后输出的join命令,需要带上参数--control-plane表示把master控制节点加入集群
kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba --control-plane检查状态
kubectl get node kubectl get pods --all-namespaces5. 加入Kubernetes Node在node1上执行
向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:
kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba集群网络重新安装,因为添加了新的node节点
检查状态
kubectl get node kubectl get pods --all-namespaces7. 测试kubernetes集群在Kubernetes集群中创建一个pod,验证是否正常运行:
$ kubectl create deployment nginx --image=nginx $ kubectl expose deployment nginx --port=80 --type=NodePort $ kubectl get pod,svc访问地址:http://NodeIP:Port
``
六、在集群环境部署项目



