external-dns介绍和基本使用

external-dns用来将集群内的pod,service,ingress等资源注册到外面的dns上,这样集群外的服务可通过统一的dns访问到集群内的服务,external-dns支持将域名注册到不同的域名服务,如aws,linode,或coredns,bind-dns等。external-dns支持众多kubernetes资源到外部域名服务的注册发布,具体支持的资源类型可进入source目录查看,同时也支持众多的外部域名服务支持,具体可进入provider目录查看。 项目主页:https://github.com/kubernetes-sigs/external-dns 本文主要使用bind作为外部dns服务进行演示测试,将集群内的service,ingress,和istio-gateway,istio-virtualservice注册到外面的dns上。 域名划分 首先我们需要对域名做一个划分: svc.mydomain.com kubernetes集群内服务域名,此处我们集群内外使用相同的域 hosts.mydomain.com 主机节点的dns解析域 mydomain.com 基础服务 部署bind bind的主配置文件修改了本地监听的ip地址,注释掉了ipv6的监听,使用tsig-keygen -a hmac-sha256 externaldns命令生成了认证密匙并配置到了配置文件中,加入forwarders转发配置,此处要求配置为客户基础环境中的。 [root@vm10-77-1-87 ~]# cat /etc/named.conf // // named.conf // // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS // server as a caching only nameserver (as a localhost DNS resolver only). // // See /usr/share/doc/bind*/sample/ for example named configuration files. // // See the BIND Administrator's Reference Manual (ARM) for…

探索client-go中的exec和cp的原理

开发kubernetes控制器中可能涉及到进入特定的container中执行命令的操作,或者拷贝文件等操作,此时我们可能会借助client-go提供的这个工具去实现: "k8s.io/client-go/tools/remotecommand" // 构建请求 req := client.RESTClient().Post(). Resource("pods"). Name(podName). Namespace(namespace). SubResource("exec") req.VersionedParams(&v1.PodExecOptions{ Container: containerName, Command: cmd, Stdin: false, Stdout: true, Stderr: true, TTY: true, }, scheme.ParameterCodec) // 创建执行器 exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL()) // 执行命令 exec.Stream(remotecommand.StreamOptions{ Stdin: nil, Stdout: &buf, Stderr: &buf, Tty: true, }) 上面代码执行时会向apiserver发起一个请求,apiserver会通过代理机制将请求转发给相应节点上的kubelet服务,kubelet会通过cri接口调用runtime的接口发起流式接口中的Exec()接口进入到container执行。针对一般化的命令调用,输入参数和输出结果多数以文本为主,并不会占用带宽和apiserver的资源,但是当设计到文件拷贝的时候则会占用较多带宽,因此在实际使用时这种方式拷贝大文件来说可能并不是最优方案。 此处顺便描述一下如kubectl工具对cp命令的原理,其实也是调用的exec接口,然后执行tar命令进行文件的拷贝动作: # 从容器向外拷贝,通过tar命令压缩将输出重定向到标准输出 tar cf - <srcFile# 从外面向容器内拷贝,将标准输入数据通过tar解压写入到container内的文件目录 tar --no-same-permissions --no-same-owner -xmf - # 或 tar -xmf - 考虑到上面所说的带宽问题,在实际使用时也可向kubelet直接发起exec请求,只要通过client-go将pod所在节点实现查询一下即可,当然还会设计一些端口,证书问题,下面是一个直接向kubelet发起请求的示例代码。 package main import…

kubernetes基础 – 管理守护进程

damonset一般运行在集群的所有节点上,是一些常驻服务,通常可以用来收集日志,作为存储节点,运行监控进程等。 下面是一个日志收集的daemonset的定义: apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd-elasticsearch namespace: kube-system labels: k8s-app: fluentd-logging spec: selector: matchLabels: name: fluentd-elasticsearch updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: "100%" template: metadata: labels: name: fluentd-elasticsearch spec: # nodeSelector: # node-role.kubernetes.io/worker: "true" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule containers: - name: fluentd-elasticsearch image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2 resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: varlibdockercontainers…

kubernetes基础 – 管理有状态服务

statefulset区别于deployment有两个最重要的特性:有序性,固定性。 适用的场景 StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值: 稳定的、唯一的网络标识符 稳定的、持久的存储 有序的、优雅的部署和缩放 有序的、自动的滚动更新 限制 pod的持久化存储基于pvc和pv。 为保证数据安全,删除或者收缩statefulset并不会自动删除它关联的存储卷。 需要手动创建无头服务使pod的dns可解析。 删除 statefulset时,并不按照有序性执行,要求有序的话,可以在删除之前将 statefulset 缩放为 0。 默认pod管理策略(OrderedReady) 时使用滚动更新,有可能会有更新终止,需要人为修复的状况。 有序性: 每个pod都有一个序号 部署时和扩容时根据序号递增依次启动新pod 缩容时依次根据序号递减依次删除pod 固定标识 statefulset在创建pod的时候会为每个pod分配下面几个固定的标识。 固定网络标识 pod的名称和pod的主机名是根据statefulset的名称和当前pod的序号组成的:$(statefulset-name)-$(ordinal)。dns解析需要无头服务。 规则 Cluster Domain Service (ns/name) StatefulSet (ns/name) StatefulSet Domain Pod DNS Pod Hostname cluster.local default/nginx default/web nginx.default.svc.cluster.local web-{0..N-1}.nginx.default.svc.cluster.local web-{0..N-1} cluster.local foo/nginx foo/web nginx.foo.svc.cluster.local web-{0..N-1}.nginx.foo.svc.cluster.local web-{0..N-1} kube.local foo/nginx foo/web nginx.foo.svc.kube.local web-{0..N-1}.nginx.foo.svc.kube.local web-{0..N-1} 固定存储 pvc名称规则:$(tpl-metadata.name)-$(podname) pod标签 每个pod标签里会自动加一个 statefulset.kubernetes.io/pod-name 方便针对单个pod创建service。 pod管理策略 对于部署,扩缩容和更新时的并行度设置。 OrderedReady(依次) Parallel(并行,只影响扩缩操作,对更新策略不生效) 更新策略 手动(需要手动删除pod)…

kubernetes基础 – 管理无状态服务

考虑到性能和可用性,通常一个服务会有多个服务实例,在k8s中通过多个pod实现。 无状态服务是各个pod完全是一样,彼此可替代。 有状态服务是各个pod不完全一样,不可彼此替代,比如pod关联特定存储卷。 对于以下场景可以使用replicaset: 稳定的、唯一的网络标识符。 稳定的、持久的存储。 有序的、优雅的部署和缩放。 有序的、自动的滚动更新。 replicaset讲解 replicaset 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。 replicaset通过pod的metadata.ownerReferences对应的replicaset。如果匹配的pod没有这个值扩不是控制器,那么replicaset将捕获纳管这个pod。 ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是接使用 ReplicaSet,除非 你需要自定义更新业务流程或根本不需要更新。 示例replicaset: apiVersion: apps/v1 kind: ReplicaSet metadata: name: frontend labels: app: guestbook tier: frontend spec: # modify replicas according to your case replicas: 3 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: php-redis image: gcr.io/google_samples/gb-frontend:v3 操作:…

kubernets基础 – 基础对象讲解

kubernetes中api资源由特定的规范进行定义,api资源由组,版本和类型三部分组成,简称gvk。一个gvk确定一种对象类型,对该类型由对应的结构对其进行定义。kubernetes中对象的存储和传输可以使用protobuf,yaml和json三种序列化形式。 pod pod是kubernetes中最小可部署单元。pod由一组container构成,包括业务容器,init容器,还有一个特殊的pause容器。 下面是一个简单的pod定义。 apiVersion: v1 kind: Pod metadata: name: webserver labels: app: webserver spec: containers: - name: webserver image: nginx:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 # hostPort: 8080 # hostIP: "169.169.1.1" name: http protocol: TCP initContainers: - name: init-dir image: busybox:latest workingDir: /tmp command: - /bin/sh - -c args: - "mkdir -p test" env: - name: MY_ENV value: "123456" - name: ANOTHER_ENV valueFrom: configMapKeyRef: name: test-cm key: CM_ENV…

kubernetes基础 – 常用命令

kubectl命令将用户的请求经过处理转换为apiserver的相应接口提交给apiserver处理。 可通过kubectl -v=8查看提交的详细信息。 资源的增删改查 创建资源 kubectl create -f - -f filename/directory/url -n namespace -l kubectl create -h ​ kubectl create service loadbalancer test --tcp=80:80 kubectl create deployment test --image=nginx ​ kubectl apply 删除资源 kubectl delete pod name kubectl delete pod/name -n namespace -l k8s-app=canal -f kubectl delete ns kubectl delete pod/all -all kubectl delete -h 编辑资源 KUBE_EDITOR=vim kubectl edit cm -n kube-system canal-config kubectl patch deployment test --patch='{"spec": {"template": {"spec":…

kubernetes网络 – metallb讲解

metallb用来实现在私有化搭建的裸机环境中实现负载均衡器的功能,在没有云环境的情况下通过metallb将service暴露到网络环境中,供其他系统访问。 https://metallb.universe.tf/ 部署metallb kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml 创建配置 metallb监视名为config或metallb-config(helm部署)的configmap资源,我们创建这个资源之后它就开始工作了。 下面是layer 2模式下的配置示例,其中的addresses配置为预留的ip地址段,可配置多个。 [root@master3 ~]# cat metallb-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: namespace: metallb-system name: config data: config: | address-pools: - name: default protocol: layer2 addresses: # 可配置为下列形式或者192.168.1.0/24形式,根据预留的网段具体决定 # 可配置多个 - 10.77.1.220-10.77.1.240 kubectl apply -f metallb-configmap.yaml 测试 [root@master3 ~]# kubectl run nginx --image=nginx --port=80 [root@master3 ~]# kubectl expose pod nginx --port=80 --target-port=80 --type=LoadBalancer [root@master3 ~]# kubectl get svc…