2021-03-14 15:04:51
摘要:一、资源准备
ElasticSearch 安装有最低安装要求,如果执行 Helm 安装命令后 Pod 无法正常启动,请检查是否符合最低要求的配置。
1、资源要求
ElasticSearch节点
CPU最小要求
内存最小要求
Kubernetes master
核心数 2
内存 2Gi
Kubernetes data
核心数 1
内存 2Gi
Kubernetes client
核心数 1
内存 2Gi
2、ElasticSearch 集群环境
集群名称
类型
副本
存储
网络模式
描述
elasticsearch
Master
3
5Gi
ClusterIP
主节节点,用于控制 ES 集群
elasticsearch
Data
3
50Gi
ClusterIP
数据节点,用于存储 ES 数据
elasticsearch
Client
2
无
NodePort(30200)
负责处理用户请求,实现请求转发、负载均衡
es-master 搭建一个 elasticsearch 至少需要 3 个 Pod 以防止集群脑裂。
es-data 数据节点至少需要 2 个 Pod 。数据节点将保留数据、接收查询和索引请求。
es-client 做为协调 elasticsearch 集群。至少需要 2 个。用于集群连接,并充当 HTTP 代理。如果不使用 es-clinet 那么 es-data 充当协调,尽量避免在较大的集群上这样做。
3、Kibana 环境信息
应用名称
副本数目
存储大小
网络模式
描述
Kibana
1
无
NodePort(30601)
用于展示 ElasticSearch 数据的应用
二、提前下载镜像
提前将要部署的应用的镜像下载,避免安装时因为镜像下载过慢而导致安装失败。这里我们主要用到的两个镜像。考虑与fluentd兼容,建议使用7.6.0
docker pull elasticsearch:7.6.0
docker pull kibana:7.6.0
三、创建集群证书
ElasticSearch 7.x 版本默认安装了x-pack插件,并且部分功能免费,这里我们配置安全证书文件。
1、生成证书文件
# 运行容器生成证书
docker run --name ……
阅读全文
2021-03-11 18:19:24
摘要:和上文中rabbitMq的搭建过程类似
1、查看可使用的版本
helm repo add aliyuncs https://apphub.aliyuncs.com
helm repo update
helm repo list
helm search repo redis-ha --versions
2、拉去指定版本的配置
helm pull aliyuncs/redis-ha --version=4.3.3
tar -xf redis-ha-4.3.3.tgz
tree redis-ha
3、修改storageClass
注意:我们有3台node节点,如果只有2台node节点还需要将replicas值改成2(1主1从)
如果想设置密码,可以跟进说明设置
cat redis-cluster-values.yaml-EOF
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
image:
repository: redis
tag: 5.0.6-alpine
pullPolicy: IfNotPresent
## replicas number for each component
replicas: 3
## Kubernetes priorityClass name for the redis-ha-server pod
# priorityClassName:
## Custom labels for the redis pod
labels: {}
## Pods Service Account
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
serviceAccount:
## Specifies whether a ServiceAccount should be created
##
create: true
## The name of the ServiceAccount to use.
## If n……
阅读全文
2021-03-10 19:29:38
摘要:1、查看可使用tabbitmq-ha的版本
helm repo add aliyuncs https://apphub.aliyuncs.com
helm repo update
helm repo list
helm search repo rabbitmq-ha --versions
2、拉去指定版本的配置
helm pull aliyuncs/rabbitmq-ha --version=1.33.0
tar -xf rabbitmq-ha-1.33.0.tgz
3、查看文件
tree rabbitmq-ha
# 参考
├── charts # 依赖文件
├── Chart.yaml # 这个chart的版本信息
├── templates #模板
│ ├── deployment.yaml
│ ├── _helpers.tpl # 自定义的模板或者函数
│ ├── ingress.yaml
│ ├── NOTES.txt #这个chart的信息
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml #配置全局变量或者一些参数
4、修改value文件中的StorageClass
负责value文件,重命名为rabbitmq-cluster-values.yaml,并修改如下:
## Data Persistency
persistentVolume:
enabled: true
## If defined, storageClassName: storageClass
## If set to -, storageClassName: , which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS OpenStack)
……
阅读全文
2021-03-09 20:23:03
摘要:前提条件,先到腾讯云购买一块cfs
这里加上cfs的ip地址为:172.16.0.8
一、挂载cfs
1. 启动 NFS 客户端
yum install nfs-utils
2. 创建待挂载目标目录
mkdir -p /nfs/
3. 挂载文件系统
sudo mount -t nfs -o vers=4.0,noresvport 172.16.0.8:/ /nfs
4. 创建k8s文件夹用于存k8s的文件夹
cd ../nfs
mkdir k8s #这里加上我们把文件都存储在cfs文件系统下的k8s目录下
二、设置开机自动挂载
第一步挂载cfs虽然成功,但当服务器重启时,要重新执行挂载。因此我们要实现开机自动挂载,这里使用autofs来实现
yum install autofs -y
vim /etc/auto.master
/nfs /etc/auto.misc
vim /etc/auto.misc
k8s -rw,soft,intr 172.16.0.8:/k8s
systemctl enable autofs
三、配置授权
# 清理rbac授权
kubectl delete -f nfs-rbac.yaml -n kube-system
# 编写yaml
cat nfs-rbac.yaml-EOF
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: []
resources: [persistentvolumes]
verbs: [get, list, watch, create, delete]
- apiGroups: []
resources: [persistentvolumeclaims]
verbs: [get, list, watch, update]
- apiGroups: [storage.k8s.io]
……
阅读全文
2021-03-04 13:49:27
摘要:以下都在master节点执行
一、安装Ingress
编辑官方的mandatory.yaml文件,只是在最后加入LimitRange配置,其他保留原始设置
cat mandatory.yaml-EOF
apiVersion: 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: i……
阅读全文
2021-03-03 18:03:35
摘要:本文介绍k8s集成的搭建过程:
搭建环境:腾讯云centos8.2
服务器4台:
master: 172.16.0.2
node1: 172.16.0.3
node2: 172.16.0.4
node3: 172.16.0.5
1.配置服务器名称
分别在每台服务器上设置
hostnamectl --static set-hostname k8s-master
hostnamectl --static set-hostname k8s-node1
hostnamectl --static set-hostname k8s-node2
hostnamectl --static set-hostname k8s-node3
以下2-8步骤在所有服务器上运行
2.关闭防火墙
systemctl stop firewalld #防止端口不开发,k8s集群无法启动
systemctl disable firewalld
3.关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
4.关闭swap
vim /etc/fstab 永久关闭 注释swap那一行(访问内存分区,k8s无法启动)
swapoff -a 临时关闭
free 可以通过这个命令查看swap是否关闭了
5.将桥接的IPV4流量传递到iptables 的链
cat /etc/sysctl.d/k8s.conf EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
#加载模块
modprobe br_netfilter
6.安装Docker及同步时间
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O/etc/yum.repos.d/docker-ce.repo
# 我们安装docker-ce-3:19.03.13-3.el8版本,避免与k8s版本不兼容
yum install -y docker-ce-3:19.03.13-3.el8
systemctl sta……
阅读全文
2021-01-25 11:40:01
摘要:# 查看所有 pod 列表, -n 后跟 namespace, 查看指定的命名空间
kubectl get pod
kubectl get pod -n kube
kubectl get pod -o wide
# 查看 RC 和 service 列表, -o wide 查看详细信息
kubectl get rc,svc
kubectl get pod,svc -o wide
kubectl get pod pod-name -o yaml
# 显示 Node 的详细信息
kubectl describe node 192.168.0.212
# 显示 Pod 的详细信息, 特别是查看 pod 无法创建的时候的日志
kubectl describe pod pod-name
eg:
kubectl describe pod redis-master-tqds9
# 根据 yaml 创建资源, apply 可以重复执行,create 不行
kubectl create -f pod.yaml
kubectl apply -f pod.yaml
# 基于 pod.yaml 定义的名称删除 pod
kubectl delete -f pod.yaml
# 删除所有包含某个 label 的pod 和 service
kubectl delete pod,svc -l name=label-name
# 删除所有 Pod
kubectl delete pod --all
# 查看 endpoint 列表
kubectl get endpoints
# 执行 pod 的 date 命令
kubectl exec pod-name -- date
kubectl exec pod-name -- bash
kubectl exec pod-name -- ping 10.24.51.9
# 通过bash获得 pod 中某个容器的TTY,相当于登录容器
kubectl exec -it pod-name -c container-name -- bash
eg:
kubectl exec -it redis-master-cln81 -- bash
# 查看容器的日志
kubectl logs pod-name
kube……
阅读全文
2020-12-09 11:08:58
摘要:Request-scoped context
在 Go 服务中,每个传入的请求都在其自己的goroutine 中处理。请求处理程序通常启动额外的 goroutine 来访问其他后端,如数据库和 RPC服务。处理请求的 goroutine 通常需要访问特定于请求(request-specific context)的值,例如最终用户的身份、授权令牌和请求的截止日期(deadline)。当一个请求被取消或超时时,处理该请求的所有 goroutine 都应该快速退出(fail fast),这样系统就可以回收它们正在使用的任何资源。
Go 1.7 引入一个 context 包,它使得跨 API 边界的请求范围元数据、取消信号和截止日期很容易传递给处理请求所涉及的所有 goroutine(显示传递)。
核心接口:
如何将 context 集成到 API 中
在将 context 集成到 API 中时,要记住的最重要的一点是,它的作用域是请求级别 的。例如,沿单个数据库查询存在是有意义的,但沿数据库对象存在则没有意义。
目前有两种方法可以将 context 对象集成到 API 中:
The first parameter of a function call:首参数传递 context 对象,比如,参考 net 包 Dialer.DialContext。此函数执行正常的 Dial 操作,但可以通过 context 对象取消函数调用。
Optional config on a request structure:在第一个 request 对象中携带一个可选的 context 对象。例如 net/http 库的 Request.WithContext,通过携带给定的 context 对象,返回一个新的 Request 对象。
Do not store Contexts inside a struct type
使用 context 的一个很好的心智模型是它应该在程序中流动,应该贯穿你的代码。这通常意味着您不希望将其存储在结构体之中。它从一个函数传递到另一个函数,并根据需要进行扩展。理想情况下,每个请求都会创建一个 context 对象,并在请求结束时过期。
不存储上下文的一个例外是,当您需要将它放入一个结构中时,该结构纯粹用作通过通道传递的消息。如下例所示。
type ……
阅读全文
2020-12-05 16:43:06
摘要:channels 是一种类型安全的消息队列,充当两个 goroutine 之间的管道,将通过它同步的进行任意资源的交换。chan 控制 goroutines 交互的能力从而创建了 Go 同步机制。当创建的 chan 没有容量时,称为无缓冲通道。反过来,使用容量创建的 chan 称为缓冲通道。
要了解通过 chan 交互的 goroutine 的同步行为是什么,我们需要知道通道的类型和状态。根据我们使用的是无缓冲通道还是缓冲通道,场景会有所不同,所以让我们单独讨论每个场景。
Unbuffered Channels
ch := make(chan struct{})
无缓冲 chan 没有容量,因此进行任何交换前需要两个 goroutine 同时准备好。当 goroutine 试图将一个资源发送到一个无缓冲的通道并且没有goroutine 等待接收该资源时,该通道将锁住发送 goroutine 并使其等待。当 goroutine 尝试从无缓冲通道接收,并且没有 goroutine 等待发送资源时,该通道将锁住接收 goroutine 并使其等待。
无缓冲信道的本质是保证同步。
func main() {
c:= make(chan string)
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
c - `foo`
}
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
printIn(`Message` + -c)
}()
wg.Wait()
}
第一个 goroutine 在发送消息 foo 之后被阻塞,因为还没有接收者准备好。规范中对这种行为进行了很好的解释:
Receive 先于 Send 发生。
好处: 100% 保证能收到。
代价: 延迟时间未知。
Buffered Channels
buffered channel 具有容量,因此其行为可能有点不同。当 goroutine 试图将资源发送到缓冲通道,而该通道已满时,该通道将锁住 goroutine并使其等待缓冲区可用。如果通道中有空间,发送可以立即进行,goroutine 可以继续。当goroutine 试图从缓冲通道接收数……
阅读全文
2020-12-04 17:47:56
摘要:Share Memory By Communicating
传统的线程模型(通常在编写 Java、C++ 和Python 程序时使用)程序员在线程之间通信需要使用共享内存。通常,共享数据结构由锁保护,线程将争用这些锁来访问数据。在某些情况下,通过使用线程安全的数据结构(如Python的Queue),这会变得更容易。
Go 的并发原语 goroutines 和 channels 为构造并发软件提供了一种优雅而独特的方法。Go 没有显式地使用锁来协调对共享数据的访问,而是鼓励使用 chan 在 goroutine 之间传递对数据的引用。这种方法确保在给定的时间只有一个goroutine 可以访问数据。
Do not communicate by sharing memory; instead, share memory by communicating.
Detecting Race Conditions With Go
data race 是两个或多个 goroutine 访问同一个资源(如变量或数据结构),并尝试对该资源进行读写而不考虑其他 goroutine。这种类型的代码可以创建您见过的最疯狂和最随机的 bug。通常需要大量的日志记录和运气才能找到这些类型的bug。
早在6月份的Go 1.1中,Go 工具引入了一个 race detector。竞争检测器是在构建过程中内置到程序中的代码。然后,一旦你的程序运行,它就能够检测并报告它发现的任何竞争条件。它非常酷,并且在识别罪魁祸首的代码方面做了令人难以置信的工作。
var Wait sync.WaitGroup
var Counter int = 0
func main() {
for routine := 1; routine = 2; routine++ {
Wait.Add(1)
go Rountine(rountine)
}
Wait.Wait()
fmt.Print(Final Counter: %d\n, Counter)
}
func Rountine(id int) {
for count := 0; count 2; count++ {
value := Counter
value++
Counter = value
}
Wait.Done()
}……
阅读全文