Kubernetes Operator Development History

本文旨在记录对中间件、编排组件容器化部署后,实现kubernetes扩展组件Controller的过程。 Third-Parties kubernetes-client: javascript client-go kube-rs client-go源码分析 目录结构 kubernetes: contains the clientset to access Kubernetes API. discovery: discover APIs supported by a Kubernetes API server. dynamic: contains a dynamic client that can perform generic operations on arbitrary Kubernetes API objects. transport: set up auth and start a connection. tools/cache: useful for writing controllers. informers: informer group listers: lister group 代码实例 1 2 3 4 git clone https://github.com/huweihuang/client-go.git cd client-go #保证本地HOME目录有配置kubernetes集群的配置文件 go run client-go.go client-go.go ...

April 29, 2021 · 7 min · 1437 words · Me

Kubernetes ConfigMap 热更新

注:如果对kubernetes的基本概念不太清楚,建议先过一下基本的资源类型再阅读此文 先随便给个例子: 1 2 3 4 5 6 7 8 9 10 apiVersion: v1 kind: ConfigMap metadata: name: test-config data: config.yml: |- start-message: 'Hello, World!' log-level: INFO bootstrap.yml: listen-address: '127.0.0.1:8080' 我们定义了一个ConfigMap,data中定义了两个文件config.yml以及bootstrap.yml,当我们要引用当中的配置的时候,kubernetes提供了两种方案: 使用configMapKeyRef引用configMap中某个文件的内容作为Pod中容器的环境变量。 把所有configMap中的文件写到一个临时目录,将临时目录作为volume挂载到容器中,也就是configmap类型的volume。 假设现在我们有一个Deployment,它的pod模板里引用了configMap,现在我们的目标是:当configmap更新的时候,这个Deployment的业务逻辑也能随之更新。那么有哪些方案? 最好的情况是,当configMap发生变更时,直接进行hot update,做到不影响pod的正常运行。 如果无法hot update或者这样完成不了需求,就要出发对应的Deployment做一次滚动更新。 场景一: 针对可以进行热更新的容器,进行配置热更新 如果configMap由volume挂载,比如下述的投射卷,它的内容是可以更新的: 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: name: volume-test spec: containers: - name: container-test image: busybox volumeMounts: - name: all-in-one mountPath: "/projected-volume" readOnly: true volumes: - name: all-in-one projected: sources: - configMap: name: myconfigmap items: - key: config path: my-group/my-config 为了能够比较好得理解,先说明一下configMap的volume挂载机制: ...

April 24, 2021 · 2 min · 314 words · Me

Kubernetes Developement

资源模板 statefulset举例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 apiVersion: apps/v1beta1 kind: StatefulSet metadata: name: kubia spec: serviceName: kubia replicas: 2 template: metadata: labels: app: kubia spec: containers: - name: kubia image: derios/kubia ports: - name: http containerPort: 8080 volumeMounts: - name: data mountPath: /var/data volumeClaimTemplates: - metadata: name: data spec: resources: requests: storage: 1Mi accessModes: - ReadWriteOnce headless service举例 1 2 3 4 5 6 7 8 9 10 11 apiVersion: v1 kind: Service metadata: name: kubia spec: clusterIP: None selector: app: kubia ports: - name: http port: 80 storage class local PV 1 2 3 4 5 6 kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: local-storage provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 apiVersion: apps/v1 kind: StatefulSet metadata: name: local-test spec: serviceName: "local-service" replicas: 3 selector: matchLabels: app: local-test template: metadata: labels: app: local-test spec: containers: - name: test-container image: k8s.gcr.io/busybox command: - "/bin/sh" args: - "-c" - "sleep 100000" volumeMounts: - name: local-vol mountPath: /usr/test-pod volumeClaimTemplates: - metadata: name: local-vol spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "local-storage" resources: requests: storage: 368Gi Key Point 使用Local PV的实际场景 使用本地磁盘作为缓存的系统 CI/CD中用于存储构建中的系统 一些允许丢失和不需要保证可靠的数据(session, token) Local PV与HostPath的对比 hostpath: ...

April 21, 2021 · 7 min · 1432 words · Me

Kubernetes Handbook (Schedule)

内容涵盖 使用节点污点和pod容忍度阻止pod调度到特定节点 将节点亲缘性规则作为节点选择器的一种替代 使用节点亲缘性进行多个pod的共同调度 使用节点非亲缘性来分离多个pod 高级调度 在pod介绍的文章中可以看到,k8s可以通过在pod spec里面指定节点选择器,而这篇文章介绍的是后面其他逐渐加入的机制。 使用污点和容忍度阻止节点调度到特定节点 新特性: 节点污点、pod对于污点的容忍度 这些特性用于限制哪些pod可以被调度到某一个节点,也就是说只有当一个pod容忍某个节点的污点,这个pod才能被调度到该节点。 节点选择器和节点亲缘性规则,是明确在pod中添加的信息,来觉得一个pod可以或者不可以被调度到某个节点。而污点不一样,是在不修改已有pod信息的前提下,通过在节点上新增污点信息,来拒绝pod在这个节点的部署。 简单介绍污点和容忍度 我在自己的机器用minikube创建了k8s单点集群,用kubectl describe node minikube可以看到: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 k describe node minikube Name: minikube Roles: master Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux deploy=test kubernetes.io/arch=amd64 kubernetes.io/hostname=minikube kubernetes.io/os=linux minikube.k8s.io/commit=b09ee50ec047410326a85435f4d99026f9c4f5c4 minikube.k8s.io/name=minikube minikube.k8s.io/updated_at=2021_03_30T20_15_58_0700 minikube.k8s.io/version=v1.14.0 node-role.kubernetes.io/master= Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock node.alpha.kubernetes.io/ttl: 0 volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp: Tue, 30 Mar 2021 20:15:55 +0800 Taints: <none> # -----> 主节点暂时没有污点 Unschedulable: false Lease: HolderIdentity: minikube AcquireTime: <unset> RenewTime: Fri, 09 Apr 2021 14:48:12 +0800 可以看到Taints属性,表示目前这个主节点没有污点。不过这里可以举个例子: ...

April 9, 2021 · 3 min · 472 words · Me

Docker Fundamentals: AUFS

AUFS是一种Union File System,所谓的UnionFS实际上就是把不同物理位置的目录合并mount到同一个目录当中。一种典型的UnionFS的应用,就是把一张CD/DVD和一个硬盘目录联合mount在一起,然后你就可以对这个只读的CD/DVD上的文件进行修改。 AUFS又叫做Another UnionFS,后面改成Alternative UnionFS,然后又变成Advance UnionFS…..当然名字的改变叫啥不重要,本质还是没变的。2006年Junjiro Okajima开发了AUFS,完全重写了早期的UnionFS 1.X,主要目的是为了可靠性和性能,再引入一些新的功能,例如可写分支的负载均衡。不过很有意思的是,AUFS的性能比UnionFS 1.X好很多,后面UnionFS 2.x就抄AUFS的功能,而AUFS本身却没有合入到Linux主线,因为代码量太大质量也不好。虽然后面Junjiro不断提升代码质量,不断提交但是还是被Linus拒绝了。所以哪怕是今天AUFS也没进到Linux里,虽然质量已经可以了。 不过一些发行版比如:Ubuntu 10.04,Debian6.0都支持AUFS,所以也还好。我在Ubuntu 14.04演示一下例子。 首先,我们建立两个水果和蔬菜的目录,在这个目录上放一些文件,水果里有苹果和番茄,蔬菜有胡萝卜和番茄: 1 2 3 4 5 6 7 8 $ tree . ├── fruits │ ├── apple │ └── tomato └── vegetables ├── carrots └── tomato 然后输入: 1 2 3 4 5 6 7 8 9 10 11 12 # 创建一个mount目录 $ mkdir mnt # 把水果目录和蔬菜目录union mount到 ./mnt目录中 $ sudo mount -t aufs -o dirs=./fruits:./vegetables none ./mnt # 查看./mnt目录 $ tree ./mnt ./mnt ├── apple ├── carrots └── tomato 可以看到mnt目录下有三个文件,水果和蔬菜的目录被合并起来了。如果我们修改一下文件内容: ...

April 6, 2021 · 3 min · 465 words · Me