Spiga

k8s生产部署(三):安装NFS

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] …… 阅读全文

k8s生产部署(二):k8s环境搭建2

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…… 阅读全文

k8s生产部署(一):k8s环境搭建1

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…… 阅读全文

[推荐] kubectl 常用命令总结

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…… 阅读全文

Go语言实践(六):Package context

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 …… 阅读全文

Go语言实践(五):Channels

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 试图从缓冲通道接收数据,…… 阅读全文

Go语言实践(四):Package sync

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() }…… 阅读全文

Go语言实践(三):Memory Model

2020-12-03 21:15:36

摘要:需要阅读https://golang.org/ref/mem 如何保证在一个 goroutine 中看到在另一个 goroutine 修改的变量的值,如果程序中修改数据时有其他 goroutine 同时读取,那么必须将读取串行化。为了串行化访问,请使用 channel 或其他同步原语,例如 sync 和 sync/atomic 来保护数据。 在一个 goroutine 中,读和写一定是按照程序中的顺序执行的。即编译器和处理器只有在不会改变这个 goroutine 的行为时才可能修改读和写的执行顺序。由于重排,不同的goroutine 可能会看到不同的执行顺序。例如,一个goroutine 执行 a = 1;b = 2;,另一个 goroutine 可能看到 b 在 a 之前更新。 Memory Reordering 用户写下的代码,先要编译成汇编代码,也就是各种指令,包括读写内存的指令。CPU 的设计者们,为了榨干 CPU 的性能,无所不用其极,各种手段都用上了,你可能听过不少,像流水线、分支预测等等。其中,为了提高读写内存的效率,会对读写指令进行重新排列,这就是所谓的 内存重排,英文为 MemoryReordering。 这一部分说的是 CPU 重排,其实还有编译器重排。比如: 但是,如果这时有另外一个线程同时干了这么一件事:x=0 在多核心场景下,没有办法轻易地判断两段程序是“等价”的。 现代 CPU 为了“抚平” 内核、内存、硬盘之间的速度差异,搞出了各种策略,例如三级缓存等。为了让 (2) 不必等待 (1) 的执行“效果”可见之后才能执行,我们可以把 (1) 的效果保存到 store buffer: 先执行 (1) 和 (3),将他们直接写入 store buffer,接着执行 (2) 和 (4)。“奇迹”要发生了:(2) 看了下 store buffer,并没有发现有 B 的值,于是从 Memory 读出了 0,(4) 同样从 Memory 读出了 0。最后,打印出了 00。 因此,对于多线程的程序,所有的 CPU 都会提供“锁”支持,称之为 barrier,或者 fence。它要求:barrier 指令要求所有对内存的操作都必须要“扩散”到 memory 之后才能继续执行其他对 memory 的操作。因此,我们可以用高级点的 atomic com…… 阅读全文

Go语言实践(二):Goroutine

2020-11-30 20:05:56

摘要:Processes and Threads 操作系统会为该应用程序创建一个进程。作为一个应用程序,它像一个为所有资源而运行的容器。这些资源包括内存地址空间、文件句柄、设备和线程。 线程是操作系统调度的一种执行路径,用于在处理器执行我们在函数中编写的代码。一个进程从一个线程开始,即主线程,当该线程终止时,进程终止。这是因为主线程是应用程序的原点。然后,主线程可以依次启动更多的线程,而这些线程可以启动更多的线程。 无论线程属于哪个进程,操作系统都会安排线程在可用处理器上运行。每个操作系统都有自己的算法来做出这些决定。 Goroutines and Parallelism Go 语言层面支持的 go 关键字,可以快速的让一个函数创建为 goroutine,我们可以认为 main 函数就是作为 goroutine 执行的。操作系统调度线程在可用处理器上运行,Go运行时调度 goroutines 在绑定到单个操作系统线程的逻辑处理器中运行(P)。即使使用这个单一的逻辑处理器和操作系统线程,也可以调度数十万 goroutine 以惊人的效率和性能并发运行。 并发不是并行。并行是指两个或多个线程同时在不同的处理器执行代码。如果将运行时配置为使用多个逻辑处理器,则调度程序将在这些逻辑处理器之间分配 goroutine,这将导致 goroutine 在不同的操作系统线程上运行。但是,要获得真正的并行性,您需要在具有多个物理处理器的计算机上运行程序。否则,goroutines 将针对单个物理处理器并发运行,即使 Go 运行时使用多个逻辑处理器。 Keep yourself busy or do the work yourself 比如我们想监听一个端口,但并不知道它什么时候返回,我们可能会使用一个select来永远阻塞,如下代码: func main() { http.HandleFunc(/, func(w http.ResponseWriter, r *http.Request)) { fmt.FprintIn(w, Hello, GrpherCon SG) } go func() { if(err := http.listenAndServe(:8080, nil); err != nil) { log.Fatal(err) } }() sele…… 阅读全文

Go语言实践(一):Error

2020-11-28 20:24:53

摘要:Error error类型是go语言的一种内置类型,使用的时候不用特定去import,他本质上是一个接口 //http://golang.org/pkg/builtin/#error type error interface{ Error() string //Error()是每一个订制的error对象需要填充的错误消息,可以理解成是一个字段Error } 我们经常使用 errors.New() 来返回一个 error 对象。 //http://golang.org/src/pkg/errors/errors.go type errorString struct { s String } func (e *errorString) Error() string { return e.s } 基础库中有大量自定义的error,如bufio //http://golang.org/src/pkg/bufio/bufio.go var { ErrInvalidUnreadByte = errors.New(bufio: invalid use of UnreadByte) ErrInvalidUnreadRune = errors.New(bufio: invalid use of UnreadRune) ErrBufferFull = errors.New(bufio: Buffer full) ErrNegativeCount = errors.New(bufio: negative count) } errors.New()返回的是内部errorString对象的指针 //http://golang.org/src/pkg/errors/errors.go //New returns an error that formats as the given text func New(text string) error { return errorString{text} } Error vs Exception 各个语言的演进历史: C:单返回值,一般通过传递指针作为入参,返回值为 int 表示成功还是失败。 C++:引入了 exception,但是无法知道被调用方会抛出什么异常 Java:引入了 checked exception…… 阅读全文