关于k8s:K8S实战十二-为-Ingress-以及后端-Nginx-增加证书

前言后面 nginx 都是 http 协定在工作,那么加证书应该如何操作。 更新历史20200701 - 初稿 - 左程立原文地址 - https://blog.zuolinux.com/2020/07/01/nginx-https.html创立证书能够网上申请一年收费证书,也能够自建证书。上面自建证书。 下载自建证书脚本 wget -O Makefile https://raw.githubusercontent.com/kubernetes/examples/master/staging/https-nginx/Makefile创立证书文件 make keys KEY=/tmp/nginx.key CERT=/tmp/nginx.crt将证书写入到 K8S 的 secret 中 # kubectl create secret tls nginxsecret --key /tmp/nginx.key --cert /tmp/nginx.crtsecret/nginxsecret created将 nginx 配置写入到 K8S 的 configmap 中 # cat default.confserver { listen 80 default_server; listen [::]:80 default_server ipv6only=on; listen 443 ssl; root /usr/share/nginx/html; index index.html; server_name localhost; ssl_certificate /etc/nginx/ssl/tls.crt; ssl_certificate_key /etc/nginx/ssl/tls.key; location / { try_files $uri $uri/ =404; }}# kubectl create configmap nginxconfigmap --from-file=default.confconfigmap/nginxconfigmap created整合后端 Pod 和证书,应用 Service 公布[root@master01 ~]# cat nginx-app.yaml apiVersion: v1kind: Servicemetadata: name: my-nginx labels: run: my-nginxspec: type: NodePort ports: - port: 8080 targetPort: 80 protocol: TCP name: http - port: 443 protocol: TCP name: https selector: run: my-nginx---apiVersion: apps/v1kind: Deploymentmetadata: name: my-nginxspec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: volumes: - name: secret-volume secret: secretName: nginxsecret - name: configmap-volume configMap: name: nginxconfigmap containers: - name: nginxhttps image: bprashanth/nginxhttps:1.0 ports: - containerPort: 443 - containerPort: 80 volumeMounts: - mountPath: /etc/nginx/ssl name: secret-volume - mountPath: /etc/nginx/conf.d name: configmap-volume[root@master01 ~]# kubectl apply -f nginx-app.yaml service/my-nginx createddeployment.apps/my-nginx created查看运行状况 ...

September 18, 2020 · 2 min · jiezi

关于k8s:K8S实战十-Service

前言Pod 曾经胜利运行起来了,然而有两个问题。 一是这些 Pod 无奈从集群内部间接拜访到,二是 Pod 呈现故障自愈后,IP 会发生变化。 如何解决这两个问题,这里有一个十分重要的概念:Service 更新历史20200625 - 初稿 - 左程立原文地址 - https://blog.zuolinux.com/2020/06/25/about-service.htmlService 的意义和特点对一组 Pod 提供负载平衡(工作在 TCP/UDP 4 层)避免 Pod 更换 IP 失联,即服务发现通过 label selector 关联 PodService 工作原理Service 是由 kube-proxy 组件加上 iptables/LVS 独特实现。说白了就是通过 kube-proxy 生成了一堆 iptables 规定,通过 iptables 规定来转发数据。 iptables 转发: K8S 默认的转发设置。抉择后端 Pod 为随机抉择。当 Pod 没有响应,连贯会失败,并没有健康检查机制。须要配合 Pod 就绪探测器来确保拜访到衰弱的 Pod。当集群规模达到上万个服务时,iptables 转发效率会显著升高。LVS转发: 基于内核哈希表,性能弱小,具备更高网络吞吐量。实用于 Pod 量级大,转发规定更多的大规模集群。LVS 反对更多的 Pod 负载平衡调度算法。LVS 只负责负载平衡和代理性能,残余的包过滤和SNAT等操作还是须要 iptables 解决,但这些操作规定数量不会因 Pod 数量的减少而减少。也叫 IPVS 。Service 的默认工作形式创立 Pod 和 默认Service,进行默认工作状态的测试。 ...

September 18, 2020 · 3 min · jiezi

关于k8s:K8S实战八-Job-和-CronJob

前言容器分为两类 在线业务 - 服务类容器须要继续不中断的提供服务,容器须要始终运行 离线业务 - 工作类容器个别执行一次性工作,比方统计日志数据等,运行实现后容器即可敞开 更新历史20200618 - 初稿 - 左程立原文地址 - https://blog.zuolinux.com/2020/06/18/controller-job-cronjob.htmlJobcat job.yaml apiVersion: batch/v1kind: Jobmetadata: name: job-testspec: template: metadata: name: job-test spec: containers: - name: test-job image: busybox command: ["echo", "test job!"] restartPolicy: Never参数restartPolicy 只能是 Never 或者 onFailure 启动 [root@master01 ~]# kubectl apply -f job.yaml job.batch/job-test created运行状态 [root@master01 ~]# kubectl get podNAME READY STATUS RESTARTS AGEjob-test-t2gbw 0/1 ContainerCreating 0 12s[root@master01 ~]# kubectl get podNAME READY STATUS RESTARTS AGEjob-test-t2gbw 0/1 Completed 0 24s查看运行后果 ...

September 18, 2020 · 3 min · jiezi

关于k8s:K8S实战七-有状态应用之-MySQL-集群

前言本节应用 StatefulSet 控制器部署一个 MySQL 集群,而后进行宕机测试,察看集群是否能够失常复原应用并且不失落数据。 实现的集群有如下特色: 是一个主从复制的 MySQL 集群1 个主节点, 多个从节点从节点可能程度扩大所有的写操作,只能在主节点上执行读操作能够在所有节点上执行更新历史20200615 - 初稿 - 左程立原文地址 - https://blog.zuolinux.com/2020/06/15/statefulset-mysql-cluster.html所需服务资源所需资源为: 一个 ConfigMap两个 Service一个 StatefulSetConfigMapkubectl apply -f https://k8s.io/examples/application/mysql/mysql-configmap.yamlServicekubectl apply -f https://k8s.io/examples/application/mysql/mysql-services.yamlMySQL StatefulSetwget https://k8s.io/examples/application/mysql/mysql-statefulset.yaml批改 mysql-statefulset.yaml, 应用上一节创立的 NFS 动静存储卷 volumeClaimTemplates: - metadata: name: data annotations: volume.beta.kubernetes.io/storage-class: managed-nfs-storage spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi创立 MySQL 有状态利用 kubectl apply mysql-statefulset.yaml写入数据测试写入数据 kubectl run mysql-client --image=mysql:5.7 -i --rm --restart=Never -- mysql -h mysql-0.mysql <<EOFCREATE DATABASE test;CREATE TABLE test.messages (message VARCHAR(250));INSERT INTO test.messages VALUES ('hello');EOF查看从机是否能够读取到数据 ...

September 18, 2020 · 2 min · jiezi

关于k8s:云图说-通过Helm模板快速部署中间件应用

摘要:通过全容器化Helm模板,疾速部署中间件利用。云容器引擎基于Kubernetes Helm规范的模板提供对立的资源管理与调度,高效地实现了模板的疾速部署与前期治理,大幅简化了Kubernetes资源的装置治理过程。 Helm是治理Kubernetes应用程序的打包工具。 点击“理解更多”,对于CCE,你想晓得的都在这里! 号外!!!华为云官网开发者推广招募打算正在炽热进行中,点击立刻理解详情 点击关注,第一工夫理解华为云陈腐技术~

September 18, 2020 · 1 min · jiezi

关于k8s:Jenkins-X-3x-alpha初见面

Jenkins X很棒的改良 作者:James Strachan 咱们非常高兴地发表Jenkins X版本3的alpha公布。 你能够在这里浏览更多对于架构和组件的概述。 与版本2相比,该版本有很多长处,更易于应用、了解和治理。对于不同的基础设施和云提供商,它的配置更加灵便和简略。 新版本与helm 3、helmfile、kpt和/或kustomize的任何组合都能很好地工作。 对于那些应用过Jenkins X版本2的人,你能够查看两个版本的比拟。 咱们还通过新的jx-preview插件增加了基于helmfile的预览环境加强,这使得制作更简单的预览更加容易,比方: 为预览应用多个命名空间应用每个预览命名空间或将预览部署到共享命名空间(例如通过Canaries)应用helmfile革除资源咱们当初通过Terraform为三大公共云中的两大云提供了反对: 亚马逊谷歌Azure的反对越来越靠近了;如果你想帮忙它做好筹备,退出咱们的slack。 当应用你的笔记本电脑或本地kubernetes集群不应用terraform,咱们反对: Minikube这样你就能够在笔记本电脑上运行Jenkins X了On Premise这样你就能够应用任何的kubernetes集群咱们正在致力改善装置/降级的用户体验;咱们心愿很快就能有一种纯正的terraform(或terraform云)形式来在私有云上启动Jenkins X的装置,并缩小工作量。咱们心愿很快就能在博客上写进去…… 所以请应用并让咱们晓得你的想法吧!如果你能想到任何咱们能够改良的办法,请通知咱们! 点击浏览网站原文。 为下一代继续交付合作提供一个中立的家。 CDF(Continuous Delivery Foundation,继续交付基金会)是许多快速增长的继续交付我的项目,包含Jenkins、Jenkins X、Spinnaker和Tekton,的供应商中立家园。CDF通过凋谢模型、培训、行业指南和可移植性重点来反对DevOps从业者。 Linux基金会是非营利性组织,是技术生态系统的重要组成部分。Linux基金会通过提供财务和智力资源、基础设施、服务、流动以及培训来反对创立永续开源生态系统。在共享技术的创立中,Linux基金会及其我的项目通过共同努力造成了不凡胜利的投资。扫描二维码关注LFAPAC微信公众号。

September 18, 2020 · 1 min · jiezi

关于k8s:EIK收集日志

装置配置elasticsearch下载helm包helm pull elastic/elasticsearch容器中生成elastic证书#!/bin/bashRELEASE=7.9.1docker run --name elastic-charts-certs -i -w /app \ harbor-k8s.iwgame.com/containers/elasticsearch:$RELEASE \ /bin/sh -c " \ elasticsearch-certutil ca --out /app/elastic-stack-ca.p12 --pass '' && \ elasticsearch-certutil cert --name security-master --dns security-master --ca /app/elastic-stack-ca.p12 --pass '' --ca-pass '' --out /app/elastic-certificates.p12" && \docker cp elastic-charts-certs:/app/elastic-certificates.p12 ./ && \docker rm -f elastic-charts-certs && \openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem创立secrets生成账号密码和证书kubectl create secret -n efk generic elastic-certificates --from-file=elastic-certificates.p12kubectl create secret -n efk generic elastic-certificate-pem --from-file=elastic-certificate.pemkubectl create secret -n efk generic elastic-credentials --from-literal=password=123 --from-literal=username=elastic批改values.yaml文件volumeClaimTemplate: accessModes: [ "ReadWriteOnce" ] storageClassName: "iwgame-nfs-storage" resources: requests: storage: 30GiesConfig: elasticsearch.yml: | cluster.name: "docker-cluster" network.host: 0.0.0.0 xpack.security.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12extraEnvs: - name: ELASTIC_PASSWORD valueFrom: secretKeyRef: name: elastic-credentials key: password - name: ELASTIC_USERNAME valueFrom: secretKeyRef: name: elastic-credentials key: usernamesecretMounts: - name: elastic-certificates secretName: elastic-certificates path: /usr/share/elasticsearch/config/certs装置elasticsearchhelm install --namespace=logging elastic ./查看pod运行状态个别都须要装置奇数,因为我只有两个node所以部署了2个,生产环境倡议装置三个 ...

September 17, 2020 · 2 min · jiezi

关于k8s:centos7使用Minikube快速搭建出Kubernetes本地实验环境踩坑集锦及解决方案

centos7应用Minikube"疾速搭建"出Kubernetes本地试验环境(踩坑集锦及解决方案)先决条件 查看Linux是否反对虚拟化,验证输入是否为非空如何开启虚拟化grep -E --color 'vmx|svm' /proc/cpuinfo 装置 kubectl判断是否胜利装置kubectl kubectl version 装置MinikubeLinux curl -Lo minikube https://kubernetes.oss-cn-han... && chmod +x minikube && sudo mv minikube /usr/local/bin/ 启动minikube start 为了拜访海内的资源,阿里云提供了一系列基础设施,请依照如下参数进行配置。其中常见参数 --driver=*** 从1.5.0版本开始,Minikube缺省应用本地最好的驱动来创立Kubernetes本地环境,测试过的版本 docker, kvm--image-mirror-country cn 将缺省利用 registry.cn-hangzhou.aliyuncs.com/google_containers 作为装置Kubernetes的容器镜像仓库 (阿里云版本可选)--iso-url=*** 利用阿里云的镜像地址下载相应的 .iso 文件 (阿里云版本可选)--registry-mirror=***为了拉取Docker Hub镜像,须要为 Docker daemon 配置镜像减速,参考阿里云镜像服务--cpus=2: 为minikube虚拟机调配CPU核数--memory=2048mb: 为minikube虚拟机分配内存数--kubernetes-version=***: minikube 虚拟机将应用的 kubernetes 版本当你执行minkube start会呈现这个谬误,大略意思是须要加个 --driver=none的参数 谬误一:The "docker" driver should not be used with root privileges.If you are running minikube within a VM, consider using --driver=none:https://minikube.sigs.k8s.io/... X Exiting due to DRV_AS_ROOT: The "docker" driver should not be used with root privileges.加了参数当前那就恐怖了 ...

September 13, 2020 · 2 min · jiezi

关于k8s:Kubernetes世界中的虚拟机

KubeCon + CloudNativeCon资助客座文章来自红帽云平台产品治理Peter Lauterbach 加入KubeCon的人晓得,容器技术会持续存在。事实上,“Gartner预测,到2022年,超过75%的寰球组织将在生产中运行容器化应用程序,这比2019年的不到30%有了显著增长”。及时提交应用程序,使咱们放弃竞争力,并与咱们的客户根底相干。为了做到这一点,许多公司都采纳了容器框架,以提高效率和速度。适应新技术并不总是那么容易。有些应用程序可能须要应用遗留技术,或者须要投入大量工夫和精力来构建新的技术。咱们如何解决那些须要应用虚拟机的应用程序,而不使虚拟化和容器技术的治理复杂化?欢送来到KubeVirt。 KubeVirt我的项目从新构想了Kubernetes世界中的虚拟机。能够创立虚拟机,或者将其从遗留框架迁徙到kubernetes优先的治理范例中。开发人员能够应用他们现有的Kubernetes工具集来原生地治理VM,或者将这些工作负载转换为容器。这为组织和反对开发团队提供了空间,以便在对其业务有意义的事实工夫线上更新应用程序。 听起来乏味吗?兴许有点太神奇了?上面是在Kubernetes中开始试验虚拟机的一些办法。 从繁多的管制立体反对遗留架构 KubeVirt的美好之处在于,它容许开发团队将现有的应用程序从新设计为云原生、容器优先的部署,而不是让开发人员承当在Kubernetes上用不可能的工夫线从新构建所有内容的累赘。通过KubeVirt中的繁多管制立体简化了VM和容器的治理。基于获奖的KVM技术,KubeVirt提供了成熟的虚拟化能力和性能,并间接带来Kubernetes的益处。 应用程序现代化 在努力实现DevOps或云原生应用程序架构时,有三个要害思考因素:业务需要、技术需要和迁徙策略。 业务需要:现代化可能从Kubernetes性能中获益的工作负载,同时在虚拟机上放弃更传统的个性。利用这个机会来确定你将来3-5年的业务需要,并理解你从明天开始要做什么。你们都应用虚拟机了吗?你对DevOps或云原生感兴趣吗?如果你对Kubernetes感兴趣,然而你晓得虚拟机上存在依赖关系,那么能够在转换过程中包含KubeVirt作为测试选项。技术思考:当你晓得Kubernetes将呈现在你的将来,请思考KubeVirt的技术能力。Kubernetes提供了与传统虚拟机不同的治理范例。调整大小、备份甚至工作负载认证的策略可能与你当初所经验的不同。KubeVirt的次要长处之一是,通过将虚拟机和容器放在繁多管制立体下,能够简化治理工具集的数量。KubeVirt是一个动静我的项目--如果这个平台明天不能100%满足你的需要,不要放弃它。迁徙策略:包含文件和web服务器、.NET应用程序、Java和企业数据库在内的工作负载是从传统VM迁徙到Kubernetes的现实抉择。从这样的VM开始,在转移到更简单的工作负载之前,你能够试验最简略的设置。在这里,你能够将虚拟机导入KubeVirt,并利用最佳实际来进行VM镜像解决或Windows装置。依照本人的节奏倒退 在Kubernetes中开始应用VM是很容易(KubeVirt能够供下载并作为操作器部署),而且倒退起来也很简略和无效。如果你筹备应用KubeVirt,那么能够启动一个新的虚拟机,或者将现有的VM迁徙到KubeVirt。扩大集群就像退出一个节点一样简略,并且齐全通过操作器执行。反对的虚拟机数量没有限度,而且虚拟机具备传统虚拟机环境中常见的雷同数据持久性。当你对该平台越来越相熟,能够向上扩大加强VM并最终取代传统的虚拟化。 KubeVirt被世界各地的客户和社区成员大规模利用和部署。OpenShift Virtualization当初是Red Hat OpenShift容器平台齐全反对的个性。OpenShift Virtualization是第一个基于KubeVirt的齐全受反对的产品,打消了传统应用程序栈中常常存在的操作和开发之间的竖井。 想理解更多对于KubeVirt的信息,请退出咱们的论坛、Slack(Kubernetes的#virtualization频道)、Twitter,或者退出KubeVirt社区。 点击浏览网站原文。 CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。 CNCF(云原生计算基金会)致力于培养和保护一个厂商中立的开源生态系统,来推广云原生技术。咱们通过将最前沿的模式民主化,让这些翻新为公众所用。扫描二维码关注CNCF微信公众号。

September 10, 2020 · 1 min · jiezi

关于k8s:使用Kubernetes来构建克服新的建筑成本

客座文章之前由Brad Ascar,高级解决方案架构师,在Carbon Relay博客上发表 市场数据显示,容器化的采纳是如许迅速,特地是Kubernetes在企业中的增长。例如,CNCF最近的一项考察显示,84%的企业IT受访者示意,他们在生产中运行容器,其中大部分(78%)援用Kubernetes作为编排零碎。 换句话说,容器和Kubernetes曾经成为支流。 这意味着许多企业IT和DevOps团队都在应用这项相当新的技术(它只有6年的历史),作为他们为云原生世界重建遗留IT环境的要害局部。 有很多新的IT“修建”是由绝对缺乏经验的工作人员应用新资料和新技术建造的。 然而,正如每一个修建监理和贸易人员都晓得的那样,解决新“货色”天然会带来一些问题和挑战。 这些Kubernetes构建人员遇到的一些常见问题是什么?以下是咱们在该畛域看到的或在行业内听到的一些重点。 新技术,缺乏经验 Kubernetes的新面孔,加上它的迅速遍及,导致了技术上的差距。在这项技术上有丰盛教训的人很难找到和招聘,雇佣老本也很高。依据Enterprise Project,Kubernetes的工作在全国的平均工资靠近14.5万美元。 因而,一些企业急于向前倒退,把那些原本很有成就的人放在下面,认为他们会解决。这就像让一个木匠学徒来搭建整个房子。这是一种蹩脚的开始形式,即便最终取得了可承受的后果,在此过程中也必定会呈现问题。 生疏景观 Kubernetes承诺在更少的基础设施和更低的老本下实现更大的业务敏捷性和响应能力。通常从一个应用程序开始,企业团队面临将其转换为齐全不同货色的艰巨工作。在许多状况下,它们采纳一个具备单体设计的应用程序(在事后配置的数据中心的专用硬件上的虚拟机中运行的对立堆栈),并将其合成为微服务汇合,通过云从一系列不同的起源进行配置。 尽管新的微服务和容器化办法很简单,但大多数企业团队都有能力建设一个Kubernetes集群,并在其上运行一个应用程序。让这个应用程序牢靠地运行,而后优化,这才是真正的挑战。 适度配置 当初很多公司都在产生这样的事件。他们的团队曾经应用Kubernetes,建设集群,他们曾经将大型利用分解成许多小块,这些小块是他们从云中的不同起源收集来的。他们的第一个K8s应用程序曾经启动并运行。而后,他们试图通过更改设置来对其进行一些调整,而后,砰的一声!利用解体。或者,它们没有更改任何默认值,而较大的负载或零碎上的其余压力导致系统呈现故障。 尽管他们不晓得为什么这个应用程序在1g的状况下会解体,但他们意识到在1.5g的状况下解体的几率会小一些。所以,他们尝试了2g,它在大部分工夫仿佛运行失常。然而“ok”并不能解决问题。为了升高应用程序的危险,防止停机和凌晨3点的紧急呼叫,他们将配置晋升到4g。 后果呢?一个应用程序,如果正确配置,可能在最高250mb的状况下牢靠地运行,则有375%的过载。当第二个、第三个、第四个或第100个应用程序被容器化时,同样的适度配置产生时,问题随之而来。在某个时候,零碎会解体,应用程序会解体,危险会变成理论的操作和名誉侵害。当云资源耗费的指数级增长反映在云服务提供商的每月账单上时,这种挫伤就更大了。 尽管这些团队可能缩小了必须购买和治理的基础设施的数量,并进步了业务敏捷性,但其老本往往是其老式本地硬件和vm老本的好几倍。 玩“打地鼠”式的设置 在Kubernetes清单中,IT团队能够操作两个次要的设置,并且只针对两种资源类型。有一些针对资源申请和资源限度的设置,它们利用于CPU和内存资源。再加上replicaset和主动缩放选项等概念,就会有许多可挪动的局部。应用程序是scale-up,还是scale-out?哪种形式更经济实惠? 初始设置可能在一段时间内工作良好,即便它们在谬误的中央开始,并且当初正在测量谬误的事件,或谬误的形式运行正确的事件。然而,随着程度扩大部署和新的集群上线,以及具备十分不同行为的新应用程序被退出其中,事件可能会出错。因为初始设置不再无效,IT团队心愿调整它们。 这就是“打地鼠”游戏的开始。不足对设置更改的影响的可见性,将这个过程变成了危险的猜想。兴许更重要的是,它耗费了开发人员低廉的工夫。 应用程序参数使事件进一步复杂化 只管针对Kubernetes的部署设计显著不同,应用程序依然有可调参数,团队能够对其进行批改和更改。例如,对于一个简略的数据库,团队能够设置内存和页面缓存资源的级别、数据在写入磁盘之前在内存中存在多长时间的时间段,以及容许运行多少个正本。 另一个例子是Java应用程序,其中有许多JVM设置须要设置和调优,比方堆大小和垃圾收集参数,这些设置对性能有很大影响。 应用程序可能成为“乐音街坊”,并开始影响其余应用程序的性能。在多层环境中部署时,在第一层调优参数通常绝对容易,危险也低,但在第二层和第三层,难度和危险显著减少。 简而言之,Kubernetes中容许的最小设置,加上应用程序“堆栈”的不同层上不同的可调参数,使得实现Kubernetes应用程序的性能和老本十分艰难。 总结 这并不是说IT团队最终不能失去他们须要的答案。而是说这是一项艰难、乏味、有危险的工作,而且他们须要疾速解决变动。因而,就像由木匠、水管工和电工组成的建筑工人一样,这些企业团队所从事的工作须要艰辛、乏味、有时还有危险。他们正在做的IT工作相当于建造一个新的构造--挪动和筹备资料,初步确定新构造,并实现最初的工作。 然而,有一些新的、聪慧的办法能够确保你的IT构建人员团队防止上述列出的缺点。应用这些新办法,当他们看到本人曾经胜利建设的货色时,肯定会微笑。咱们将在下一篇文章中探讨这些新办法。请持续关注。 点击浏览网站原文。 CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。 CNCF(云原生计算基金会)致力于培养和保护一个厂商中立的开源生态系统,来推广云原生技术。咱们通过将最前沿的模式民主化,让这些翻新为公众所用。扫描二维码关注CNCF微信公众号。

September 9, 2020 · 1 min · jiezi

关于k8s:Kubernetes引入结构化日志

作者:Marek Siarkowicz(谷歌)、Nathan Beach(谷歌) 日志是可察看性的一个根本方面,也是调试的一个要害工具。然而Kubernetes日志传统上是非结构化字符串,这使得任何主动解析都很艰难,任何上游解决、剖析或查问都很难牢靠地实现。 在Kubernetes 1.19中,咱们减少了对结构化日志的反对,它原生反对(键、值)对和对象援用。咱们还更新了许多日志调用,这样在一个典型的部署中超过99%的日志量当初都迁徙到了结构化格局。 为了放弃向后兼容性,结构化日志仍将输入为字符串,其中字符串蕴含“key”=“value”对的示意。从1.19的alpha开始,日志也能够应用--logging-format=json标记以JSON格局输入。 应用结构化日志 咱们向klog库增加了两个新办法:InfoS和ErrorS。例如,以下信息的调用: klog.InfoS("Pod status updated", "pod", klog.KObj(pod), "status", status)将导致以下日志: I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"或者,如果设置了--logging-format=json标记,则会产生如下输入: { "ts": 1580306777.04728, "msg": "Pod status updated", "pod": { "name": "coredns", "namespace": "kube-system" }, "status": "ready"}这意味着上游的日志工具能够很容易地获取结构化日志数据,而不是应用正则表达式(regex)来解析非结构化字符串。这也使得解决日志更容易,查问日志更强壮,剖析日志更快。 应用结构化日志,对Kubernetes对象的所有援用都以雷同的形式进行结构化,因而你能够过滤援用特定pod的输入和日志条目。你还能够找到一些日志,这些日志批示调度器如何调度pod、如何创立pod、pod的运行状况探测以及pod生命周期中的所有其余更改。 假如你正在用pod调试一个问题。应用结构化日志,你能够筛选到仅援用感兴趣的pod的那些日志条目,而不须要扫描可能数以千计的日志行来查找相干的日志。 结构化日志不仅在手动调试问题时更有用,而且还反对更丰盛的个性,如日志中的主动模式识别或日志和跟踪数据的更严密的相关性。 最初,结构化日志能够帮忙升高日志的存储老本,因为大多数存储系统压缩结构化的key=value数据比压缩非结构化的字符串更无效。 来参加 尽管在一个典型的部署中,咱们曾经按日志量更新了超过99%的日志条目,但依然有数千个日志须要更新。抉择一个你想要改良的文件或目录,并将现有的日志调用迁徙到应用结构化日志。这是对Kubernetes做出第一份奉献的一种平凡而简略的形式! 点击浏览网站原文。 CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。 CNCF(云原生计算基金会)致力于培养和保护一个厂商中立的开源生态系统,来推广云原生技术。咱们通过将最前沿的模式民主化,让这些翻新为公众所用。扫描二维码关注CNCF微信公众号。

September 8, 2020 · 1 min · jiezi

关于k8s:警告有用的警告|让Kubernetes的使用越来越容易

作者:Jordan Liggitt(谷歌) 作为Kubernetes的维护者,咱们始终在寻找在放弃兼容性的同时进步可用性的办法。在开发个性、分类bug和答复反对问题的过程中,咱们积攒了有助于Kubernetes用户理解的信息。在过来,信息的共享仅限于公布阐明、布告电子邮件、文档和博客文章等内部办法。除非有人晓得该信息并设法找到它,否则他们不会从中受害。 在Kubernetes v1.19中,咱们增加了一个个性,容许Kubernetes API服务器向API客户机发送正告。正告是应用规范的Warning响应头发送的,因而它不会以任何形式更改状态代码或响应体。这容许服务器发送正告,任何API客户端都能够轻松读取,同时放弃与以前的客户端版本兼容。 正告在kubectl v1.19+的stderr输入和k8s.io/client-go客户端库v0.19.0+的日志输入。k8s.io/client-go的设定能够按过程或按客户端笼罩。 弃用的正告 咱们应用这个新性能的第一种形式是,对应用已弃用的API(deprecated API)发送正告。 Kubernetes是一个疾速倒退的大型项目。即便对于全职从事我的项目的人来说,跟上每个版本中的变动也是一件令人生畏的事件。一种重要的扭转是API的弃用。随着Kubernetes中的API降级到GA版本,预公布的API版本将被弃用并最终被删除。 即便有一个缩短的弃用期,并且在公布阐明中蕴含了弃用,它们依然很难跟踪。在弃用期间,预公布API依然无效,容许多个版本转换为稳固的API版本。然而,咱们发现,用户通常甚至没有意识到他们所依赖的API版本曾经弃用,直到他们降级到不再提供它的版本。 从v1.19开始,每当向弃用的REST API发出请求时,都会在API响应的同时返回一个正告。此正告包含无关API将不再可用的版本的详细信息,以及替换的API版本。 因为正告来自服务器,在客户端被拦挡,所以它实用于所有的kubectl命令,包含像kubectl apply这样的高级命令,和像kubectl get --raw这样的低级命令: 这有助于受弃用影响的人晓得他们收回的申请已被弃用,他们须要多长时间来解决这个问题,以及他们应该应用什么API来代替。当用户利用本人没有创立的清单时,这尤其有用,这样他们就有工夫分割作者,要求更新版本。 咱们还意识到,应用已弃用API的人通常不是负责降级集群的同一个人,因而咱们增加了两个面向管理员的工具,以帮忙跟踪已弃用API的应用状况,并确定何时降级是平安的。 指标 从Kubernetes v1.19开始,当向已弃用的REST API端点发出请求时,在kube-apiserver过程中将apiserver_requested_deprecated_apis度量指标设置为1。此指标具备API group、version、resource、subresource的标签,以及一个removed_version标签,该标签批示不再提供API的Kubernetes版本。 这是一个应用kubectl、prom2json和jq的示例查问,用于确定API服务器的以后实例申请了哪些弃用的API: kubectl get --raw /metrics | prom2json | jq ' .[] | select(.name=="apiserver_requested_deprecated_apis").metrics[].labels'输入: { "group": "extensions", "removed_release": "1.22", "resource": "ingresses", "subresource": "", "version": "v1beta1"}{ "group": "rbac.authorization.k8s.io", "removed_release": "1.22", "resource": "clusterroles", "subresource": "", "version": "v1beta1"}这显示了弃用的extensions/v1beta1 Ingress和rbac.authorization.k8s.io/v1beta1 ClusterRole API在此服务器上被申请,将在v1.22中被删除。 咱们能够将这些信息与apiserver_request_total指标连接起来,以取得对于向这些API收回的申请的更多细节: kubectl get --raw /metrics | prom2json | jq ' # set $deprecated to a list of deprecated APIs [ .[] | select(.name=="apiserver_requested_deprecated_apis").metrics[].labels | {group,version,resource} ] as $deprecated | # select apiserver_request_total metrics which are deprecated .[] | select(.name=="apiserver_request_total").metrics[] | select(.labels | {group,version,resource} as $key | $deprecated | index($key))'输入: ...

September 8, 2020 · 2 min · jiezi

关于k8s:Kubernetes如何自动检测和处理弃用的API

作者:Stepan Stipl,DoiT International高级云架构师。客座文章最后在DoiT International博客上发表。 随着Kubernetes 1.16可用一段时间,并开始在许多托管Kubernetes平台上迟缓推出,你可能据说过API弃用(deprecation)。尽管解决起来相当简略,然而如果无人参加,这种更改可能会重大地中断你的服务。 API弃用是什么? 随着Kubernetes的个性集的倒退,API也必须倒退以反对这种变动。有一些规定旨在保障兼容性和稳定性。这种状况不会在每个版本中都产生,但最终,你将不得不应用新的API版本和格局,因为旧的API将不再受反对。 为什么这对于1.16版本如此重要? 在最近几个K8s版本中保留了一些弃用的API,最终在Kubernetes 1.16版本中被齐全删除。即以下API组和版本: Deployment — extensions/v1beta1, apps/v1beta1 and apps/v1beta2NetworkPolicy — extensions/v1beta1PodSecurityPolicy — extensions/v1beta1DaemonSet — extensions/v1beta1 and apps/v1beta2StatefulSet — apps/v1beta1 and apps/v1beta2ReplicaSet — extensions/v1beta1, apps/v1beta1 and apps/v1beta2如果尝试在1.16中应用其中之一创立资源,操作将会失败。 如何查看我是否受到影响? 你能够手动遍历所有清单,但这可能相当耗时。如果有多个团队部署到集群中,或者在一个中央没有以后的所有清单,那么很容易失落一些清单,并且可能十分不理论。这就是kubent(Kube-No-Trouble)来帮忙的中央。 问题是什么? 用于创立给定资源的API版本的信息通常是不容易找到,因为资源总是在外部转换为首选存储版本并存储在首选存储版本中。然而。如果你应用kubectl或Helm来部署资源,原始清单也存储在集群中,咱们能够利用它。如果是kubectl,则模式为kubectl.kubernetes.io/last-applied-configuration正文;如果是Helm,则模式为ConfigMap或Secret。 如何解决弃用产生的问题 最简略的办法是装置: sh -c "$(curl -sSL 'https://git.io/install-kubent')"这将把kubent的最新版本装置到/usr/local/bin中。 (如果你和我一样,不置信他人在博客文章中公布的随机脚本,请下载针对你的平台的最新版本,而后解压缩到你喜爱的任何中央。) 配置kubectl的以后上下文,以指向你想要检查和运行kubent工具的集群: 图1:kubent运行的示例输入 Kubent将连贯到你的集群,检索所有可能受到影响的资源,扫描并打印那些受到影响的资源的摘要。 你还能够应用-f json标记来取得JSON格局的输入,这更适宜让你将其集成到你的CI/CD流水线中或进一步处理结果。对于可用配置选项的更多细节在doitintl/kube-no-trouble仓库的README文件中形容。 我应该如何解决检测到的资源? 在某些状况下,这就像扭转manifest中的apiVersion一样简略,但在其余状况下,构造可能曾经扭转,须要调整。另外,要留神,版本之间有很多默认值会发生变化(对于这方面的好文章是David Schweikert的Kubernetes 1.16 API deprecations and changed defaults),因而,仅更改apiVersion并利用雷同的清单,就会失去不同的后果。例如,StatefulSet的updateStrategy.type从OnDelete更改为RollingUpdate,导致了十分不同的行为。 以前应用的kubectl convert命令现已弃用,可能不能依据后面提到的默认值正确地转换资源。 最好的办法可能是简略地利用资源(如果你应用kubent检测到它们,那么你曾经有了这些资源)并从API检索新版本。这将确保资源被正确地转换为新版本。你可能曾经留神到,kubectl在某种程度上不确定地返回的版本。要申请一个特定的API版本,应用残缺的模式: kubectl get ingress.v1beta1.extensions -o yaml欢送反馈! ...

September 2, 2020 · 1 min · jiezi

关于k8s:Kubernetes从Beta前进避免永久Beta

作者:Tim Bannister,The Scale Factory 在Kubernetes中,个性遵循一个已定义的生命周期。首先,作为一个感兴趣的开发人员的一瞬。兴许,在网上的探讨中,在相当于咖啡餐巾的网上画上草图。这种毛糙的工作通常会变成KEP(Kubernetes加强倡议,Kubernetes Enhancement Proposal),而后通常会转换成代码。 对于Kubernetes v1.20及当前版本,咱们的重点是帮忙这些代码过渡到稳固的个性。 我提到的生命周期运行如下: Alpha→Beta→GA 通常,alpha个性在默认状况下是不启用的。你通过设置性能门(feature gate)来关上它们;通常,通过在应用该个性的每个组件上设置一个命令行标记。 (如果你通过托管服务 - 如AKS、EKS、GKE等 - 应用Kubernetes,那么运行该服务的供应商可能曾经决定为你启用哪些个性了)。 将一个现有的、alpha的个性转化为beta阶段是一个明确的过程。这一点很重要,因为测试版(beta)个性是默认启用的,个性标记依然存在,所以集群操作人员能够抉择不启用。 一套相似但更彻底的分级规范管制着向GA(general availability)的过渡,也被称为“稳固(stable)”。GA个性是Kubernetes的一部分,并承诺在以后次要版本中保留它们。 默认测试版性能能够让Kubernetes和它的贡献者取得有价值的真实世界的反馈。然而,激励机制却不匹配。一旦一个个性被默认启用,人们就会应用它。即便有一些细节须要解决,Kubernetes的REST API和常规的工作形式意味着任何将来稳固的API都将与最新的beta API兼容:当一个beta个性降级到GA时,API对象不会进行工作。 特地是对于API及其资源,将性能从beta转移到GA的动机远不如从alpha转移到beta。想要某个特定个性的供应商有很好的理由帮忙代码达到默认启用个性的水平,除此之外,这个过程就不那么清晰了。 KEP跟踪的不仅仅是代码改良。实质上,任何须要与更宽泛的社区进行交换的货色都值得应用KEP。也就是说,大多数KEP笼罩了Kubernetes的个性(以及实现这些个性的代码)。 你可能晓得Ingress在Kubernetes曾经有一段时间了,但你是否意识到它实际上在2015年就开始进入beta了?为了帮忙推动事件向前,Kubernetes的架构特地兴趣小组(SIG)有一个新的办法。 防止永恒测试版 对于Kubernetes REST API来说,当一个新个性的API达到beta时,就开始倒计时了。测试版API当初有九个月的工夫: 达到GA,并弃用beta,或领有一个新的测试版(并弃用之前的测试版)。须要明确的是,此时只有REST API会受到影响。例如,APIListChunking是一个beta个性,但它自身不是REST API。目前还没有打算主动弃用APIListChunking,或任何其余非REST API的个性。 如果REST API达到了9个月的倒计时,那么下一个Kubernetes版本将会弃用该API版本。在Kubernetes 9个月后公布的第一个测试版之后,REST API不能抉择持续放弃测试版。 这对你意味着什么 如果你正在应用Kubernetes,那么你很有可能正在应用beta个性。就像我说的,有很多。和Ingress一样,你可能正在应用CronJob,或PodSecurityPolicy,或其余。更大的可能性是,你运行在一个至多启用了一个测试版个性的管制立体上。 如果你正在应用或生成应用像Ingress这样的beta API的Kubernetes清单,则须要打算批改它们。以后的API将依照打算(我后面提到的9个月)被弃用,9个月后那些弃用的API将被删除。此时,为了与Kubernetes放弃同步,你应该曾经进行了迁徙。 这对Kubernetes的贡献者意味着什么 这里的动机仿佛很分明:让个性稳固。保障beta个性将会被废除,这是一个很大的激励,因而想要该个性的人们会持续致力,直到该个性的代码、文档和测试曾经筹备好达到稳固,并失去Kubernetes在理论应用中公布的证据的反对。 这对生态系统意味着什么 在我看来,这些看似严格的措施是很有意义的,而且对Kubernetes也有益处。通过一种实用于所有不同非凡趣味组(SIG)的规定来弃用现有API,有助于防止停滞并激励修复。 假如一个API达到了beta,而后理论教训表明它是不正确的——从根本上说,这个API有缺点。随着9个月的倒计时,相干人员有了办法和理由来批改和公布解决问题案例的API。欢送任何心愿应用这个已被弃用的API的人应用它 - Kubernetes是开源的 - 然而他们的需要不用妨碍这个个性的倒退。 点击浏览网站原文。 CNCF (Cloud Native Computing Foundation)成立于2015年12月,隶属于Linux  Foundation,是非营利性组织。 CNCF(云原生计算基金会)致力于培养和保护一个厂商中立的开源生态系统,来推广云原生技术。咱们通过将最前沿的模式民主化,让这些翻新为公众所用。扫描二维码关注CNCF微信公众号。

September 2, 2020 · 1 min · jiezi

关于k8s:K8S集群学习笔记整理三

参考文章主参考:《Centos7.6部署k8s v1.16.4高可用集群(主备模式)》《应用kubeadm在Centos8上部署kubernetes1.18》《应用kubeadm部署k8s集群[v1.18.0]》 1、环境规划a. 主机布局# 主机名 Centos版本 ip docker version flannel version Keepalived version 主机配置 备注# master01 7-8.2003 192.168.1.121 19.03.9 v0.11.0 v1.3.5 2C2G control plane# master02 7-8.2003 192.168.1.122 19.03.9 v0.11.0 v1.3.5 2C2G control plane# master03 7-8.2003 192.168.1.123 19.03.9 v0.11.0 v1.3.5 2C2G control plane# work01 7-8.2003 192.168.1.131 19.03.9 / / 2C2G worker nodes# work02 7-8.2003 192.168.1.132 19.03.9 / / 2C2G worker nodes# work03 7-8.2003 192.168.1.133 19.03.9 / / 2C2G worker nodes# VIP 7-8.2003 192.168.1.200 19.03.9 v0.11.0 v1.3.5 2C2G 在control plane上浮动# client 7-8.2003 192.168.1.201 / / / 2C2G client# 共有7台服务器,3台control plane【1台VirtualPC】,3台work,1台client不动。# 试验机-16G内存:集群节点全副退出master1后,根本内存占用99%,kubectl get nodes查问常常回绝,后内存改为 1200b. vagrant 筹备centos7筹备略。 ...

August 29, 2020 · 5 min · jiezi

关于k8s:为什么使用OPA而不是原生的Pod安全策略

客座文章之前由Mohamed Ahmed在Magalix博客上发表 在本文中,咱们将演示如何应用OPA执行最细粒度的安全策略。请留神,本文是一个系列的一部分,咱们将基于“OPA作为代码介绍”和“集成OPA到Kubernetes”中取得的常识进行。如果你还没有这样做,请浏览本系列中已发表的文章。 你可能曾经相熟Pod安全策略,能够在其中对Pod利用十分特定的安全控制。例如,应用Linux内核性能,应用主机命名空间、网络、端口或文件系统,以及其余许多性能。应用OPA,你还能够对pods施加相似的管制,在本实验室中,咱们将创立一个OPA策略,不容许在pods中创立有特权的容器。特权容器对主机的拜访级别比非特权容器高。 为什么应用OPA而不是原生的Pod安全策略? 应用Pod安全策略来执行咱们的安全策略并没有什么问题。然而,依据定义,PSP只能利用于pods。它们不能解决其余Kubernetes资源,如Ingresses、Deployments、Services等。OPA的弱小之处在于它能够利用于任何Kubernetes资源。OPA作为一个许可控制器部署到Kubernetes,它拦挡发送到API服务器的API调用,并验证和/或批改它们。相应地,你能够有一个对立的OPA策略,实用于零碎的不同组件,而不仅仅是pods。例如,有一种策略,强制用户在其服务中应用公司的域,并确保用户只从公司的镜像存储库中提取镜像。请留神,咱们应用的OPA是应用kube-mgmt部署的,而不是OPA Gatekeeper。 Rego的策略代码 在本文中,咱们假如你曾经相熟了OPA和Rego语言。咱们还假如你有一个正在运行的Kubernetes集群,该集群部署了OPA和kube-mgmt容器。无关装置阐明,请参阅咱们的前一篇文章。咱们的no-priv-pod.rego文件如下所示: package kubernetes.admissiondeny[msg] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])}input_containers[c] { c := input.request.object.spec.containers[_]}input_containers[c] { c := input.request.object.spec.initContainers[_]}让咱们简要地浏览一下这个文件: 第1行:蕴含package。留神,你必须应用kubernetes.admission让政策工作。第2行:Deny是默认对象,它将蕴含咱们须要执行的策略。如果所蕴含的代码计算结果为true,则将违反策略。第3行:咱们定义了一个变量,它将包容pod中的所有容器,并从稍后定义的input_containers[c]接管值。第4行:如果pod蕴含“privileged”属性,则该语句为true。第5行:当用户尝试运行特权容器时显示给他们的音讯。它包含容器名称和违规的平安上下文。第7-9行:input_containers[c]函数从申请对象中提取容器。留神,应用了_字符来遍历数组中的所有容器。在Rego中,你不须要定义循环—下划线字符将主动为你实现此操作。第10-12行:咱们再次为init容器定义函数。请留神,在Rego中,能够屡次定义同一个函数。这样做是为了克服Rego函数中不能返回多个输入的限度。当调用函数名时,将执行两个函数,并应用AND操作符组合输入。因而,在咱们的例子中,在一个或多个地位中存在一个有特权的容器将违反策略。部署策略 OPA会在opa命名空间的ConfigMaps中找到它的策略。要将咱们的代码利用到ConfigMap中,咱们运行以下命令: kubectl create configmap no-priv-pods --from-file=no-priv-pod.regokube-mgmt边车(sidecar)容器在opa命名空间中继续监督API服务器,以便你只需创立ConfigMap就能够部署策略。 运行策略 让咱们通过尝试部署一个特权容器来确保咱们的策略是无效的: kubectl -n default apply -f - <<EOTapiVersion: v1kind: Podmetadata: name: nginx-privileged labels: app: nginx-privilegedspec: containers: - name: nginx image: nginx securityContext: privileged: true #falseEOTError from server (Privileged container is not allowed: nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validating-webhook.openpolicyagent.org" denied the request: Privileged container is not allowed: nginx, securityContext: {"privileged": true}请留神,咱们无意将pod部署到默认命名空间,因为咱们的admission webhook将疏忽在opa命名空间或kube-system中创立的任何资源。 ...

August 28, 2020 · 1 min · jiezi

关于k8s:探究K8S-v119-GA的Seccomp

什么是Seccomp?Seccomp(全称:secure computing mode)在2.6.12版本(2005年3月8日)中引入linux内核,是一种限度零碎调用的平安机制。在严格模式下,将过程可用的零碎调用限度为四种:read,write,exit,sigreturn,其余的零碎调用都会杀死过程。过滤模式下,能够指定容许那些零碎调用,Seccomp进行过滤的形式是基于应用SECCOMP_MODE_FILTER模式的BPF过滤器,并且零碎调用过滤的形式与对数据包的过滤形式雷同。例如,您可能心愿为过程提供CAP_NET_ADMIN性能,但通过阻塞accept和accept4零碎调用的形式不容许它承受套接字上的连贯。 从linux/seccomp.h 的内核源代码中看,seccomp_data构造的样子如下: struct seccomp_data { int nr; __u32 arch; __u64 instruction_pointer; __u64 args[6]; };通过该构造能够看出,咱们能够基于syscall,基于其参数或基于它们的组合进行过滤。 kubernetes中的seccompSeccomp在Kubernetes 1.3版本中作为Alpha性能引入,应用PodSecurityPolicy上的正文将Seccomp配置文件利用于所需的Pod。 例如咱们要将一个seccomp profile 设置到某个pod范畴: annotations: seccomp.security.alpha.kubernetes.io/pod: "localhost/profile.json"或者咱们设置到容器范畴: annotations: container.security.alpha.kubernetes.io/<container-name>: "localhost/profile.json"在1.19版中,Seccomp 性能 GA,将新的seccompProfile字段增加到pod和容器的securityContext对象中。 apiVersion: v1kind: Podmetadata: name: audit-pod labels: app: audit-podspec: securityContext: seccompProfile: type: RuntimeDefault containers: - name: test-container image: hashicorp/http-echo:0.2.3 args: - "-text=just made some syscalls!" securityContext: allowPrivilegeEscalation: false此处咱们能够看到咱们应用了RuntimeDefault, 该type是k8s默认的容器运行时profile。 此处可能的值为: Unconfined - 如果没有其余抉择,Seccomp不会利用于容器过程(这是Kubernetes中的默认设置)。RuntimeDefault - 应用默认的容器运行时配置文件。Localhost - 指定自定有的profile文件。当type 为该值时,此时必须指定localhostProfile字段的值。比方: ...

August 28, 2020 · 1 min · jiezi

关于k8s:如何基于K8s构建下一代DevOps平台

简介: OAM是阿里巴巴与微软联合推出的凋谢利用模型,旨在解耦利用研发、利用运维与基础设施人员在利用生命周期中各自的关注点,清晰责任与界线,聚焦本身业务,同时又仍然能严密合作。以后云原生DevOps体系现状如何?面临哪些挑战?如何通过OAM解决云原生DevOps场景下的诸多问题?云原生开发利用模型OAM(Open Application Model)社区核心成员孙健波将为大家一一解答,并分享如何基于OAM和Kubernetes打造有限能力的下一代DevOps平台。 一 什么是DevOps?为什么基于Kubernetes构建?2009年举办了第一届DevOpsDays大会,DevOps名字被首次提出。到2010年,DevOps的概念越来越火,出了What is DevOps的文章,解说了DevOps的概念,方法论及配套的工具。简略来说,研发工程师须要和运维工程师深度的单干,同时通过一系列工具保障研发更加顺畅,从而更容易的接触生产环境。到2013年,Docker呈现了,工程师能够第一次到软件生产环境中定义,通过Docker image实现单机软件的交付和散发。此时DevOps开始缓缓落地。2015年开始,DevOps相干的工具越来越多,资源利用率呈现了一些问题,CNCF的成立使得DevOps的实际往Kubernetes上走。 阿里在Kubernetes上的实际也获得了十分好的成绩。在规模方面,阿里外部集成了数十个节点能够达到上万的集群,同时具备高性能和平安个性,秒级扩容,神龙+平安容器。具备极致的弹性,分钟级拆解私有云计算资源,有限资源池。另一方面,Kubernetes社区曾经具备十分丰盛的DevOps生态根底性能,包含镜像托管、CICD流水线、工作编排、公布策略、镜像打包、散发、丰盛的利用运行时的负载撑持、丰盛弹性和利用扩容能力。 为什么阿里基于Kubernetes构建DevOps平台? 1)阿里基于Kubernetes的有限资源池与基础设施能力 大规模 – 单集群最高可达10000节点、百万Pod高性能 – 秒级扩容,智能伸缩,神龙 + 平安容器极致弹性 – 分钟级拆解私有云计算资源,有限资源池2)社区围绕Kubernetes曾经具备丰盛的DevOps生态根底性能 源码到容器镜像仓库,Kubernetes是容器平台事实标准:Github/DockerHubCI/CD流水线、工作编排、公布策略:Argo/Teckton/Spinnaker/Jenkins-X/Flagger镜像打包、散发:Helm/CNAB丰盛的利用运行负载撑持:Deployment(无状态)/StatefulSet(有状态)/OpenKruise(原生有状态加强)丰盛的弹性和利用扩缩容能力:HPA/KEDA二 基于Kubernetes的DevOps平台新挑战下图展现了一个云原生下的DevOps流水线的典型流程。首先是代码的开发,代码托管到Github,再接入单元测试的工具Jenkins,此时根本研发已实现。再接着到镜像的构建,波及到配置、编排等。云原生中能够用HELM打包利用。打包好的利用部署到各个环境中。但整个过程中会面临很多挑战。首先,在不同的环境须要不同的运维能力。 其次,配置的过程中要创立云上数据库,须要另外关上一个控制台来创立数据库。还须要配置负载平衡。在利用启动当前还须要配置额定的性能,包含日志、策略、平安防护等等。能够发现,云资源和DevOps平台体验是割裂的,外面充斥着借助内部平台创立的过程。这对老手来说是十分苦楚的。 挑战一:云资源与 DevOps 平台体验割裂DevOps流程中充斥着大量须要内部平台创立的过程: 挑战二:研发、运维、基础设施关注点耦合下图是罕用的K8s的YAML配置文件,大家常常吐槽这个配置文件很简单。简略来说YAML配置文件能够分为三大块,一块是运维比较关心的配置,包含实例数,策略和公布。第二块是研发关怀的,波及到镜像、端口号等。第三块是基础设施工程师看得懂的,如调度策略等。K8s的配置文件中将方方面面的信息都耦合在一起,这对K8s工程师来说是非常适合的,然而对利用侧的终端工程师而言,有很多不须要关怀的配置指标。 DevOps流程中不足对“利用”这个概念的形容K8s 的 YAML文件的定位并不是终端用户挑战三:平台的自定义封装,简略却能力有余DevOps平台对K8s能力封装形象,只剩下5个Deployment的字段须要研发填写。从用户角度而言,这种设置十分好用简略。然而针对略微简单的利用,波及到利用状态治理,健康检查等等一系列的操作,此时这5个字段是不够的。 挑战四:CRD 扩大能力弱小,DevOps 平台无奈间接复用CRD(Customize Resource Definition)扩大能力弱小,简直所有软件都能够通过CRD的形式进行扩大,包含数据库、存储、平安、编排、依赖治理、公布等。然而对DevOps平台来说,下面接口并没有向用户裸露,导致无奈间接复用。 挑战五:DevOps 平台开发的新能力应用门槛高如果平台想要扩大一些能力,而原生的主动扩缩容能力不太适合,心愿开发定时的扩缩容YAML文件,随着业务状况而设置。但此时用户应用YAML的门槛十分高,不分明如何应用YAML。随着新能力开发越来越多,能力之间会呈现抵触,这也十分难以治理。 运维同学怎么晓得这个扩大能力怎么用?看 CRD?看配置文件?看 …… 文档? 扩大能力间呈现抵触,导致线上故障比方:CronHPA 和 默认 HPA 被同时装置给了同一个利用 K8s 扩大能力之间的抵触关系,如何无效治理?如何无效的对运维透出? 挑战六:不同 DevOps 平台须要齐全从新对接很多云原生实际中会遇到的问题,即须要定义非常复杂的YAML,这种形式能够解决企业外部所有问题,然而挑战在于很难与生态进行对接。如RDS,SLB的能力都嵌到YAML文件中,无奈复用,简直不具备原子化能力。同时无奈合作,无奈提供给兄弟部门或生态应用,只能给外部关闭生态应用。下层零碎不同利用对接DevOps平台时,须要写不同格局的YAML,这也是十分苦楚的。 难以了解,必须通过界面可视化透出无奈复用,简直不具备原子化能力无奈合作,只能外部关闭生态应用三 OAM利用模型的技术原理Component组件OAM中常见的概念是Component组件,齐全从研发角度定义的待部署单元。下图右侧是YAML中Component的例子,其中黄色局部能够灵便自定义。OAM中会定义规范的架构ContaineriseWorkload,示意工作负载局部,外面是待部署单元的具体形容。这时就能够解决关注点拆散的问题,帮忙利用侧工程师去掉很多细节,只须要关怀开发须要关注的端口号,镜像等等。 应答挑战一,在OAM中能够定义数据库表白资源须要应用云资源,Workload中能够依据本人的须要定义不同的组件,包含基于虚拟机的利用、或者老的Function利用。组件是利用开发者关怀的。 ...

August 27, 2020 · 1 min · jiezi

关于k8s:Kubernetes-119强调积极的态度

终于,咱们迎来了 Kubernetes 1.19 版本,这是2020年的第二个版本,也是迄今为止最长的公布周期,总共继续20周。它由33项加强性能组成。12个加强性能进入稳定版,18个加强性能进入测试版,13个加强性能进入alpha版。 因为 COVID-19、George Floyd 抗议以及咱们作为公布团队经验的其余一些全球性事件,因而1.19版本与惯例版本齐全不同。因为这些事件,咱们决定调整咱们的时间表,并让 SIG、工作组和贡献者有更多的工夫来实现工作。额定的工夫也让大家有工夫关注 Kubernetes 我的项目之外的生存,并确保他们的精神状态更加良好。 贡献者是 Kubernetes 的外围,Kubernetes 的行为准则要求人们都很优良,只管咱们的世界动荡不安,但咱们从社区中看到的只是平凡和谦卑。 次要主题将 Kubernetes 反对窗口减少到一年长期反对(LTS)工作组在2019年初进行的一项考察显示在以后的9个月反对期内,很大一部分 Kubernetes 用户未能降级。这一点以及考察中的其余反馈表明,如果将补丁反对期缩短至12-14个月,则30%的用户可能将其部署放弃在反对的版本上。无论用户应用的是自建版还是商业发行版,状况都是如此。因而,缩短反对期将导致超过 80% 的用户应用受反对的版本,而不是当初的 50-60%。一年一度的反对期可为用户提供所需的缓冲期,并且更合乎相熟的年度布局周期。从 Kubernetes 1.19 版本开始,反对窗口将缩短到一年。 贮存容量追踪传统上,Kubernetes 调度器基于这样的假如:集群中任何中央都能够应用额定的持久性存储,并具容量有限。拓扑束缚解决了第一点,但到目前为止,Pod 调度依然没有思考残余的存储容量可能不足以启动一个新的 pod。存储容量追踪是一个新的 Alpha 个性,它通过为 CSI 驱动程序增加一个 API 来解决这个问题,以报告存储容量,并在 Kubernetes 调度器中为 Pod 抉择节点时应用该信息。该性能可作为反对本地卷和其余容量限度较大的卷类型的动静预配置的根底。 通用长期存储Kubernetes 提供了卷插件,其生命周期与 Pod 绑定,可用作长期空间(例如内置的 emptydir 卷类型),也能够将一些数据加载到 Pod 中(例如内置的configmap 和 secret 卷类型)。新的通用暂存卷 alpha 性能容许任何现有的反对动静供给的存储驱动程序被用作 ephemeral 卷,并将该卷的生命周期绑定到 Pod。它能够用来提供不同于根磁盘的长期存储,例如长久内存或者该节点上的独立本地磁盘。反对所有用于卷供给的 StorageClass 参数。反对PersistentVolumeClaims 反对的所有性能,如存储容量跟踪、快照和还原以及卷的大小调整。 CSI Volume 衰弱监测CSI 健康状况监控的 Alpha 版本随 Kubernetes 1.19一起公布。该性能使 CSI 驱动程序可能与 Kubernetes 共享来自底层存储系统的异样卷情况,以便将其作为事件报告在 PVC 或 Pod 上。此性能是 Kubernetes 进行程序检测和解决单个卷衰弱问题的根底。 ...

August 27, 2020 · 2 min · jiezi

关于k8s:从PVC使用率看k8s-监控控制平面指标稳定性规范KEP

前言kubernetes家大业大,监控纷繁复杂,感兴趣的小伙伴能够看看我之前写的文章从容器监控kube-stats-metrics看k8s泛滥组件 k8s中pv使用率监控阐明尽管k8s最善于的是无状态的pod,不倡议有状态的存储型pod上然而总有些应用场景须要,比方statefulset应用的pv那么pv的使用率监控就十分有必要了咱们能够应用 kubelet_volume_stats_used_bytes/kubelet_volume_stats_capacity_bytes表征pod pv使用率 另外一种pv监控形式如果采纳云硬盘能够到对应的存储节点监控fs应用挂载状况能够轻松失去一个fs的应用状况而后依据k8s接口获取到pod和pv的映射关系向prometheus打点kubelet_volume_stats*采集原理追踪kubelet 启动 initializeModules--> fsResourceAnalyzer定时更新 podvolumestats --> updateCachedPodVolumeStats--> s.statsProvider.GetPods(从apiserver中获取的pod信息缓存到本地cache中)-->而后启动 calcAndStoreStats获取volume信息-->最终调用 volume的getmetrics()获取,路径可能是du/statFs/csi // Start eager background caching of volume stats.func (s *fsResourceAnalyzer) Start() { s.startOnce.Do(func() { if s.calcPeriod <= 0 { klog.Info("Volume stats collection disabled.") return } klog.Info("Starting FS ResourceAnalyzer") go wait.Forever(func() { s.updateCachedPodVolumeStats() }, s.calcPeriod) })}// updateCachedPodVolumeStats calculates and caches the PodVolumeStats for every Pod known to the kubelet.func (s *fsResourceAnalyzer) updateCachedPodVolumeStats() { oldCache := s.cachedVolumeStats.Load().(statCache) newCache := make(statCache) // Copy existing entries to new map, creating/starting new entries for pods missing from the cache for _, pod := range s.statsProvider.GetPods() { if value, found := oldCache[pod.GetUID()]; !found { newCache[pod.GetUID()] = newVolumeStatCalculator(s.statsProvider, s.calcPeriod, pod).StartOnce() } else { newCache[pod.GetUID()] = value } } // Stop entries for pods that have been deleted for uid, entry := range oldCache { if _, found := newCache[uid]; !found { entry.StopOnce() } } // Update the cache reference s.cachedVolumeStats.Store(newCache)}在k8s 1.17版本变动发现 kubelet_volume_stats_used_bytes等指标曾经不存在了 ...

August 11, 2020 · 2 min · jiezi

关于k8s:k8s节点亲和性

k8s节点亲和性Kubernetes中的调度策略能够大抵分为两种: 一种是全局的调度策略,要在启动调度器时配置,包含kubernetes调度器自带的各种predicates和priorities算法,具体能够参看上一篇文章;另一种是运行时调度策略,包含nodeAffinity(主机亲和性),podAffinity(POD亲和性)以及podAntiAffinity(POD反亲和性)。nodeAffinity 次要解决POD要部署在哪些主机,以及POD不能部署在哪些主机上的问题,解决的是POD和主机之间的关系。podAffinity 次要解决POD能够和哪些POD部署在同一个拓扑域中的问题(拓扑域用主机标签实现,能够是单个主机,也能够是多个主机组成的cluster、zone等。)podAntiAffinity次要解决POD不能和哪些POD部署在同一个拓扑域中的问题。它们解决的是Kubernetes集群外部POD和POD之间的关系。策略名称匹配指标反对的操作符反对拓扑域nodeAffinity主机标签In,NotIn,Exists,DoesNotExist,Gt,Lt不反对podAffinityPod标签In,NotIn,Exists,DoesNotExist反对PodAntiAffinityPod标签In,NotIn,Exists,DoesNotExist反对亲和性:利用A与利用B两个利用频繁交互,所以有必要利用亲和性让两个利用的尽可能的凑近,甚至在一个node上,以缩小因网络通信而带来的性能损耗。反亲和性:当利用的采纳多正本部署时,有必要采纳反亲和性让各个利用实例打散散布在各个node上,以进步HA,避免节点down掉,服务生效。nodeAffinity硬亲和性 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: 硬亲和性 nodeSelectorTerms: 写多个满足其中一条就能够 - matchExpressions: 能够写多个满足必须同时满足 - key: disktype operator: In values: - ssd - hard软亲和性 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 60 preference: matchExpressions: - {key: zone, operator: In, values: ["foo"]} - weight: 30 preference: matchExpressions: - {key: ssd, operator: Exists, values: []}同时指定nodeSelectorTerms和nodeSelector时必须同时满足nodeAffinity有多个nodeSelectorTerms ,pod只需满足一个nodeSelectorTerms多个matchExpressions ,pod必须都满足因为IgnoredDuringExecution,扭转labels不会影响曾经运行podPod affinity 因为业务的需要,有时会需要将pod调度到对立区域(node,机房)等,比方前端和和后端尽量放在一起,频繁交互的放在一起,这样能够缩小网络的开销,有时会出于平安思考,会将不通的pod放在不通区域,这时须要用到反亲和性。 <font color=#FF0000> requiredDuringSchedulingIgnoredDuringExecution, 硬束缚,肯定要满足,Pod的亲和性调度必须要满足后续定义的约束条件。 </font><font color=#FF0000> preferredDuringSchedulingIgnoredDuringExecution,软束缚,不肯定满足,Pod的亲和性调度会尽量满足后续定义的约束条件。 </font> pod亲和性会依据节点上正在运行的pod的标签来调度,而非node的标签,要求对节点和Pod两个条件进行匹配,其规定为:如果在具备指定标签的Node上运行了一个或多个符合条件的Pod,那么Pod应该运行在此Node上。反之怎不容许运行在此node上。能够依据kubernetes.io/hostname作为评判规范是否在一个域中。 Pod亲和性调度:podAffinity非亲和性调度:podAntiAffinity affinity: #定义亲和性 podAntiAffinity: # pod亲和性 requiredDuringSchedulingIgnoredDuringExecution: #硬束缚 - labelSelector: matchExpressions: - key: app operator: In values: - nacos topologyKey: kubernetes.io/hostname #域topologyKey: ...

August 11, 2020 · 1 min · jiezi

关于k8s:Kubernetes使用nfs做为动态存储

机器环境筹备应用StorageClass为k8s作为动静存储,大规模集群中可能会有很多PV,如果这些PV都须要运维手动来解决这也是一件很繁琐的事件,所以就有了动静供应概念,也就是Dynamic Provisioning。而咱们下面的创立的PV都是动态供应形式,也就是Static Provisioning。而动静供应的要害就是StorageClass,它的作用就是创立PV模板,进步工作效率,创PVC时会动静主动创立PV。 服务器用处10.4.2.104nfs服务器10.4.2.100-105k8s集群搭建nfs服务器10.4.2.104上搭建nfs服务器yum install rpcbindyum -y install nfs-utilskcat << EOF >> /etc/hosts/volumes 10.0.0.0/8(rw,no_root_squash,anonuid=998,anongid=994)EOFexportfs -rvsystemctl restart rpcbindsystemctl restart nfssystemctl enable nfsk8s所有节点装置nfs客户端yum -y install nfs-utilsK8S装置nfs-client创立RABCServiceAccountapiVersion: v1kind: ServiceAccountmetadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: storage-class---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: nfs-client-provisioner-runnerrules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"]---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: run-nfs-client-provisionersubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: storage-classroleRef: kind: ClusterRole name: nfs-client-provisioner-runner apiGroup: rbac.authorization.k8s.io---kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: storage-classrules: - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: leader-locking-nfs-client-provisioner namespace: storage-classsubjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: storage-classroleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.iokubectl apply -f rabc.yaml装置nfs-clientapiVersion: apps/v1kind: Deploymentmetadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: storage-classspec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: harbor-k8s.iwgame.com/containers/nfs-client-provisioner:latest volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes/ env: - name: PROVISIONER_NAME value: g.iwgame.com/nfs - name: NFS_SERVER value: 10.4.2.104 - name: NFS_PATH value: /volumes volumes: - name: nfs-client-root nfs: server: 10.4.2.104 path: /volumeskubectl apply -f deployment.yaml创立StorageClassapiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: iwgame-nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "true"provisioner: g.iwgame.com/nfs # or choose another name, must match deployment's env PROVISIONER_NAME'reclaimPolicy: Retainparameters: archiveOnDelete: "false"创立PVC测试

August 10, 2020 · 2 min · jiezi

关于k8s:支持Pod-绑定静态-IP-基于K8s的自定义控制器Enhanced-Statefulset

云妹导读: 以后,Kubernetes曾经成为云原生的事实标准, Kubernetes原生反对了功能强大的控制器——deployment 、statefulset  、daemonset。但在理论业务场景中,原生控制器无奈满足一些简单和大规模场景中的业务需要。京东智联云开发团队联合多年云原生开发与应用教训,推出了自定义控制器Enhanced statefulset。本文将把咱们的产品性能、技术思考和实现细节全面展示给云原生用户和开发者,以期帮忙大家更好地应用Kubernetes 开始本人的云原生之路。 随着云原生概念逐步深入人心,越来越多的用户开始承受和践行云原生的设计与理念。Kubernetes作为容器治理引擎,提供了弱小的容器编排能力,反对不可变基础设施与申明式Openapi,同时隔离了底层基础设施差别,曾经成为云原生的基石和事实标准。Kubernetes原生反对功能强大的控制器,例如deployment 、statefulset  、daemonset等,能够解决很多用户场景。但随着 Kubernetes 的应用范畴越来越广,原生的控制器曾经无奈满足一些简单和大规模场景中的业务需要。 以京东团体业务为例,因为历史起因,团体内很多根底运维业务包含日志、监控、拜访策略管制、服务发现等都是以IP作为实例惟一标识,这就要求Pod实例可能反对动态IP绑定。同时,咱们并不是简略地为了Kubernetes而上Kubernetes,而是须要尽量利用Kubernetes为业务提供更多的DevOps能力,比方更丰盛的降级策略,故障主动迁徙等。 基于这些思考,最终咱们决定基于CRD扩大(CustomResourceDefinitions,即自定义资源)的机制,通过自定义控制器的形式来提供Pod绑定动态IP性能。这就是本篇文章要讲的产品——Enhanced statefulset。 顾名思义,Enhanced statefulset就是咱们在statefulset的根底上对控制器做了进一步的扩大。它次要解决Pod绑定动态IP问题,同时也解决了statefulset在降级过程中不容许同时降级多个实例的限度。另外,它还能够在节点故障时反对Pod和IP的迁徙。 上面和大家分享一下Enhanced statefulset的外围性能个性: 后面曾经提到了动态IP的重要场景是业务依赖的周边组件都以IP作为实例惟一标识,所以上到Kubernetes后依然须要Pod实例放弃IP不变。置信很多用户也面临着相似的问题,上面就来分享一下实现原理。 咱们次要是通过对Enhanced Statefulset Controller 、 Scheduler、CNI这几个模块扩大来反对Enhanced Statefulset的Pod绑定动态IP。具体模块关系和性能如下图所示: ▲模块关系图▲ Enhanced Statefulset Controller 对动态IP的治理次要是保护更新Static IP CR来实现的。当Controller收到创立申请时,会首先查看要创立的实例是否曾经有对应的static IP CR记录,若记录不存在则会创立一个新的记录。在稍后scheduler实现调度,CNI实现动态IP调配后,controller会监听Pod信息并将其更新到Static IP CR中。反之若创立实例时,对应的static IP CR记录曾经存在则示意这个Pod是删除重建,Controller会将static IP CR中的信息更新到Pod上,scheduler和CNI依据pod上的配置进行亲和性调度和IP调配。 StaticIP CRD中记录了负载类型、负载名称、节点、IP和Pod信息。其中IP信息在Pod实例上以annotation taticip.jke.jdcloud.com/ip-address 形式出现,CNI就是依据这个字段来决定要调配的IP地址。节点信息则是通过affinity属性在pod上出现,这样scheduler就不须要感知节点和IP的拓扑信息,只有依照亲和性调度就能够将Pod调度到动态IP所在的节点上,简化了scheduler的解决逻辑。 1apiVersion: "jke.jdcloud.com/v1" 2kind: StaticIP 3metadata: 4  name: {{workload}}-{{podname}}-{{ipaddress}} 5spec: 6  Ref: {{workload-name}}      // 所属 workload 实例名称,如 deployment-xxxx 7  Kind: {{workload}}          // workload 类型, 如 deployment 8  Node: Node-{{name}}         // node 名称, 如 node-xxxx 9  IP: {{ipaddress}}           // 绑定的 ip 地址, 如 10.10.0.110  Pod: {{pod-name}}           // pod 名称: pod-xxxxx〈〈〈左右滑动以查看残缺代码 〉〉〉 咱们对scheduler做的扩大次要是解决Pod资源预留问题。失常流程中当绑定动态IP的Pod删除后,Pod所占用的资源也会被开释,如果有其余新调度的Pod到这个节点上就会占用以后节点的资源。这时如果绑定动态IP的Pod在此节点重建可能就会因为资源有余而失败。为了解决这个问题,咱们对scheduler做了扩大: 新增缓存:原有 Node 缓存根底上新增 staticIPNode 缓存,用于计算和缓存 staticIPPod 资源占用状况、缓存 IP 数量、Pod cpu/内存 使用量;新增predicate :PodFitsResourcesWithStaticIPPodPred Node 现有资源根底上基于 staticIPPod 占用资源再次过滤,达到资源预占目标;CheckPodAnnotationWithStaticIPPred 查看pod 是否蕴含 static ip 的指定 node annotation, 并仅保留指定 node 后果只 fit node 列表。概括起来外围思路就是将动态IP Pod所占用的资源作为一种非凡资源独自标识,在调度时进行匹配调度达到资源预占目标。 ...

August 7, 2020 · 1 min · jiezi

关于k8s:限时开放下载219页阿里技术Knative-云原生应用开发指南

你理解云原生和Knative吗? 当他人探讨此话题的时候,你是否会不知所云? 什么是Knative? Knative 是 Google 在 2018 的 Google Cloud Next 大会上公布的一款基于 Kubernetes 的 Serverless 框架。 Knative 的一个很重要的指标就是制订云原生、跨平台的 Serverless 编排规范。它的劣势在于: 基于 Kubernetes 实现 Serverless 编排;基于 Istio 实现服务的接入、服务路由的治理以及灰度公布等性能。 (Knative 体系下各个角色的协作关系) 为了进一步不便大家了解 Knative,特地给大家举荐由阿里云容器平台技术专家牛秋霖(冬岛)及阿里云容器平台高级开发工程师李鹏(元毅)联合本身的实践经验,编排的《Knative 云原生利用开发指南》,心愿可能通过文章中 25 篇重点内容帮忙更多技术爱好者疾速把握 Knative 的利用 Serverless 编排技能,揭开 Knative 的神秘面纱。 如何收费下载? 长按辨认二维码,即可收费下载此书 为什么你要读这本书? 如果你是开发者 本书能够让你疾速把握 Knative 的利用 Serverless 编排技能。应用Serverless框架之后,开发者只须要编写代码,以及配置文件,而后运行Build和Deploy就能把利用主动部署到集群,其余工作都由Knative主动解决 如果你是管理者 通过本书的介绍和案例深刻理解企业为什么须要利用的 Serverless 编排;如何对一般利用进行 Serverless 编排;利用编排和 IaaS 无服务器计算的关系以及为什么会是 Knative 等问题。 ...

July 27, 2020 · 1 min · jiezi

关于k8s:限时开放下载219页阿里技术Knative-云原生应用开发指南

你理解云原生和Knative吗? 当他人探讨此话题的时候,你是否会不知所云? 什么是Knative? Knative 是 Google 在 2018 的 Google Cloud Next 大会上公布的一款基于 Kubernetes 的 Serverless 框架。 Knative 的一个很重要的指标就是制订云原生、跨平台的 Serverless 编排规范。它的劣势在于: 基于 Kubernetes 实现 Serverless 编排;基于 Istio 实现服务的接入、服务路由的治理以及灰度公布等性能。 (Knative 体系下各个角色的协作关系) 为了进一步不便大家了解 Knative,特地给大家举荐由阿里云容器平台技术专家牛秋霖(冬岛)及阿里云容器平台高级开发工程师李鹏(元毅)联合本身的实践经验,编排的《Knative 云原生利用开发指南》,心愿可能通过文章中 25 篇重点内容帮忙更多技术爱好者疾速把握 Knative 的利用 Serverless 编排技能,揭开 Knative 的神秘面纱。 如何收费下载? 长按辨认二维码,即可收费下载此书 为什么你要读这本书? 如果你是开发者 本书能够让你疾速把握 Knative 的利用 Serverless 编排技能。应用Serverless框架之后,开发者只须要编写代码,以及配置文件,而后运行Build和Deploy就能把利用主动部署到集群,其余工作都由Knative主动解决 如果你是管理者 通过本书的介绍和案例深刻理解企业为什么须要利用的 Serverless 编排;如何对一般利用进行 Serverless 编排;利用编排和 IaaS 无服务器计算的关系以及为什么会是 Knative 等问题。 ...

July 27, 2020 · 1 min · jiezi

关于k8s:一文入门Kubernetes

Kubernetes(通常缩写为K8S)是容器编排平台。 Kubernetes提供了反对简单容器应用程序所需的所有。对于开发人员和经营人员来说,这是最便捷,最受欢迎的框架,简直所有组织的DevOps团队都宽泛应用它。 Kubernetes对计算机集群而言,就像操作系统对计算机而言。为了方便管理和服务发现,Kubernetes将组成一个应用程序的容器分组为逻辑单元。这对于微服务应用程序特地有用。 只管Kubernetes在Linux上运行,但它与平台无关,能够在裸机,虚拟机,云实例或OpenStack上运行。最新版本的Kubernetes曾经反对在Windows上运行。 Kubernetes集群中的计算机或节点分为管制立体和工作负载立体。Kubernetes 集群架构Kubernetes集群由分为两组的节点组成: 一组master节点,它们承载着管制立体组件,它们是零碎的大脑,因为它们管制着整个集群。一组形成工作负载立体的工作节点,工作负载(或应用程序)在此运行。 这两个立体独特组成了Kubernetes集群。Kubernetes Master 节点这是Kubernetes控制面板或管制立体。这里做出无关集群的决策,例如调度和检测/响应集群事件。master服务器的组件能够在集群中的任何节点上运行。以下是每个要害组件的细分: API Server集群数据存储 (etcd)Controller ManagerSchedulerDashboard (可选) 让咱们逐个探讨这些组件。 API Server 这是Kubernetes控制面板中惟一用户可拜访的API的组件,并且是你将与之交互的惟一主组件。 API Server公开了一个restful的Kubernetes API,并应用了JSON清单文件。 Kubernetes API Server公开了RESTful Kubernetes API。应用集群和其余Kubernetes组件的工程师通过此API创建对象。 集群数据存储 Kubernetes应用ETCD作为数据存储。这是一个一致性且高可用的键值存储,用于长久存储所有API对象。 因为API Server自身是无状态的,因而etcd分布式数据存储将长久保留通过API创立的对象。API Server 是与etcd通信的惟一组件。 Controller Manager kube-controller manager,它运行所有解决集群中工作的控制器。这些包含节点控制器,正本控制器,端点控制器以及服务帐户和secret控制器。这些控制器中的每一个都独自工作以维持所需状态。 控制器使你通过API创立的对象依照想要的状态运行。它们中的大多数仅创立其余对象,然而有些还与内部零碎通信(例如,通过其API的云提供商)。 Scheduler 调度程序监督新创建的Pod(一个或多个容器的组),并将其调配给节点。 调度程序决定每个应用程序实例应在哪个工作程序节点上运行。 master节点和工作节点的组件之间就是这样进行交互的。Kubernetes 工作节点 master节点解决和治理集群,而工作节点运行容器并提供Kubernetes运行时环境。 次要组件有: KubeletContainer runtimeKube-proxy 让咱们逐个探讨这些组件。 Kubelet 工作节点蕴含一个kubelet。这是次要的节点代理。它监督API服务器以查找已调配给其节点的Pod。 Kubelet执行工作并保护向主节点报告pod状态的反向通道。 Kubelet是与API Server进行对话并治理在其节点上运行的应用程序的代理。它通过API报告这些应用程序和节点的状态。 Container Runtime 每个pod内都有容器,kubelet通过Docker运行这些容器(拉取镜像,启动和进行容器等)。它还定期执行任何申请的容器活动性探测。它反对Docker和CRI-O等。 容器运行时,能够是Docker或与Kubernetes兼容的任何其余运行时。它依照Kubelet的指令在容器中运行你的应用程序。 Kube-proxy 这是节点的网络大脑,负责保护主机上的网络规定并执行连贯转发。它还负责服务中所有Pod的负载平衡。 Kubernetes服务代理(Kube-proxy)对应用程序之间的网络流量进行负载平衡。 附加组件大多数Kubernetes集群还蕴含其余几个组件。这包含DNS服务器,网络插件,日志记录代理等。 它们通常在工作节点上运行,但也能够配置为在master节点上运行。 Kubernetes 实战 ...

July 26, 2020 · 1 min · jiezi

关于k8s:一文入门Kubernetes

Kubernetes(通常缩写为K8S)是容器编排平台。 Kubernetes提供了反对简单容器应用程序所需的所有。对于开发人员和经营人员来说,这是最便捷,最受欢迎的框架,简直所有组织的DevOps团队都宽泛应用它。 Kubernetes对计算机集群而言,就像操作系统对计算机而言。为了方便管理和服务发现,Kubernetes将组成一个应用程序的容器分组为逻辑单元。这对于微服务应用程序特地有用。 只管Kubernetes在Linux上运行,但它与平台无关,能够在裸机,虚拟机,云实例或OpenStack上运行。最新版本的Kubernetes曾经反对在Windows上运行。 Kubernetes集群中的计算机或节点分为管制立体和工作负载立体。Kubernetes 集群架构Kubernetes集群由分为两组的节点组成: 一组master节点,它们承载着管制立体组件,它们是零碎的大脑,因为它们管制着整个集群。一组形成工作负载立体的工作节点,工作负载(或应用程序)在此运行。 这两个立体独特组成了Kubernetes集群。Kubernetes Master 节点这是Kubernetes控制面板或管制立体。这里做出无关集群的决策,例如调度和检测/响应集群事件。master服务器的组件能够在集群中的任何节点上运行。以下是每个要害组件的细分: API Server集群数据存储 (etcd)Controller ManagerSchedulerDashboard (可选) 让咱们逐个探讨这些组件。 API Server 这是Kubernetes控制面板中惟一用户可拜访的API的组件,并且是你将与之交互的惟一主组件。 API Server公开了一个restful的Kubernetes API,并应用了JSON清单文件。 Kubernetes API Server公开了RESTful Kubernetes API。应用集群和其余Kubernetes组件的工程师通过此API创建对象。 集群数据存储 Kubernetes应用ETCD作为数据存储。这是一个一致性且高可用的键值存储,用于长久存储所有API对象。 因为API Server自身是无状态的,因而etcd分布式数据存储将长久保留通过API创立的对象。API Server 是与etcd通信的惟一组件。 Controller Manager kube-controller manager,它运行所有解决集群中工作的控制器。这些包含节点控制器,正本控制器,端点控制器以及服务帐户和secret控制器。这些控制器中的每一个都独自工作以维持所需状态。 控制器使你通过API创立的对象依照想要的状态运行。它们中的大多数仅创立其余对象,然而有些还与内部零碎通信(例如,通过其API的云提供商)。 Scheduler 调度程序监督新创建的Pod(一个或多个容器的组),并将其调配给节点。 调度程序决定每个应用程序实例应在哪个工作程序节点上运行。 master节点和工作节点的组件之间就是这样进行交互的。Kubernetes 工作节点 master节点解决和治理集群,而工作节点运行容器并提供Kubernetes运行时环境。 次要组件有: KubeletContainer runtimeKube-proxy 让咱们逐个探讨这些组件。 Kubelet 工作节点蕴含一个kubelet。这是次要的节点代理。它监督API服务器以查找已调配给其节点的Pod。 Kubelet执行工作并保护向主节点报告pod状态的反向通道。 Kubelet是与API Server进行对话并治理在其节点上运行的应用程序的代理。它通过API报告这些应用程序和节点的状态。 Container Runtime 每个pod内都有容器,kubelet通过Docker运行这些容器(拉取镜像,启动和进行容器等)。它还定期执行任何申请的容器活动性探测。它反对Docker和CRI-O等。 容器运行时,能够是Docker或与Kubernetes兼容的任何其余运行时。它依照Kubelet的指令在容器中运行你的应用程序。 Kube-proxy 这是节点的网络大脑,负责保护主机上的网络规定并执行连贯转发。它还负责服务中所有Pod的负载平衡。 Kubernetes服务代理(Kube-proxy)对应用程序之间的网络流量进行负载平衡。 附加组件大多数Kubernetes集群还蕴含其余几个组件。这包含DNS服务器,网络插件,日志记录代理等。 它们通常在工作节点上运行,但也能够配置为在master节点上运行。 Kubernetes 实战 ...

July 26, 2020 · 1 min · jiezi

关于k8s:全网最详细的-K8s-Service-不能访问排查流程

对于新装置的 Kubernetes,经常出现的一个问题是 Service 没有失常工作。如果您曾经运行了 Deployment 并创立了一个 Service,然而当您尝试拜访它时没有失去响应,心愿这份文档能帮忙您找出问题所在。 先来相熟下Service工作逻辑: 为了实现本次演练的目标,咱们先运行几个 Pod。 $ kubectl run hostnames --image=k8s.gcr.io/serve_hostname \ --labels=app=hostnames \ --port=9376 \ --replicas=3 deployment.apps/hostnames created确认您的 Pods 是运行状态: $ kubectl get pods -l app=hostnamesNAME                        READY     STATUS    RESTARTS   AGEhostnames-632524106-bbpiw   1/1       Running   0          2mhostnames-632524106-ly40y   1/1       Running   0          2mhostnames-632524106-tlaok   1/1       Running   0          2m问题1:Service 存在吗?仔细的读者会留神到咱们还没有真正创立一个 Service - 其实这是咱们无意的。这是一个有时会被忘记的步骤,也是第一件要查看的事件。 那么,如果我试图拜访一个不存在的 Service,会产生什么呢?假如您有另一个 Pod,想通过名称应用这个 Service,您将失去如下内容: u@pod$ wget -O- hostnamesResolving hostnames (hostnames)... failed: Name or service not known.wget: unable to resolve host address 'hostnames'因而,首先要查看的是 Service 是否的确存在: $ kubectl get svc hostnamesNo resources found.Error from server (NotFound): services "hostnames" not found咱们曾经有一个罪魁祸首了,让咱们来创立 Service。就像后面一样,这里的内容仅仅是为了步骤的执行 - 在这里您能够应用本人的 Service 细节。 $ kubectl expose deployment hostnames --port=80 --target-port=9376service/hostnames exposed再查问一遍,确定一下: $ kubectl get svc hostnamesNAME        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGEhostnames   ClusterIP   10.0.1.175   <none>        80/TCP    5s与后面雷同,这与您应用 YAML 启动的 Service 一样: apiVersion: v1 kind: Service metadata: name: hostnames spec: selector: app: hostnames ports: - name: default protocol: TCP port: 80 targetPort: 9376当初您能够确认 Service 存在。 问题2:Service 是否通过 DNS 工作?从雷同 Namespace 下的 Pod 中运行: u@pod$ nslookup hostnamesAddress 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.localName:      hostnamesAddress 1: 10.0.1.175 hostnames.default.svc.cluster.local如果失败,那么您的 Pod 和 Service 可能位于不同的 Namespace 中,请尝试应用限定命名空间的名称: ...

July 18, 2020 · 3 min · jiezi

Microk8s配置

根本配置设置别名snap alias microk8s.kubectl kubectl能够用snap unalias 撤销别名指定 查看状态microk8s status --wait-ready启用插件能够用 microk8s enable --help 查看可用的插件 microk8s enable dns dashboard ingress查看组件状况microk8s.inspect通常会提醒 WARNING: IPtables FORWARD policy is DROP. Consider enabling traffic forwarding with: sudo iptables \-P FORWARD ACCEPT应用ufw敞开防火墙端口 sudo ufw allow in on cbr0 && sudo ufw allow out on cbr0sudo ufw default allow routedsudo iptables \-P FORWARD ACCEPT创立利用kubectl create deployment nginx --image=nginx--image 为指定的docker镜像地址

July 13, 2020 · 1 min · jiezi

Kubernetes各版本对应支持的docker版本列表

Kubernetes各版本对应反对的docker版本列表

July 13, 2020 · 1 min · jiezi

Pod-就地升级3kubelet-通过hash管理容器版本

k8s原生并不反对就地降级。诸如deployment等工作负载在降级的过程中,间接对Pod进行recreate。 实现容器的就地降级的另外一个前提是kubelet通过容器hash 来治理容器版本。 当创立一个Pod的时候,kubelet会计算每个容器的hash,并且把该hash值写到ContainerStatus中,该status的定义如下: // Status represents the status of a container.type Status struct { // ID of the container. ID ContainerID // Name of the container. Name string // Status of the container. State State // Creation time of the container. CreatedAt time.Time // Start time of the container. StartedAt time.Time // Finish time of the container. FinishedAt time.Time // Exit code of the container. ExitCode int // Name of the image, this also includes the tag of the image, // the expected form is "NAME:TAG". Image string // ID of the image. ImageID string // Hash of the container, used for comparison. Hash uint64 // Number of times that the container has been restarted. RestartCount int // A string explains why container is in such a status. Reason string // Message written by the container before exiting (stored in // TerminationMessagePath). Message string}其中的Hashfiled 正是咱们明天讲到的hash。 ...

July 11, 2020 · 7 min · jiezi

Pod-就地升级2Readiness-gates

什么是Readiness gates?Readiness gates,又被称为pod “ready++”,该个性kubernetes1.11被引入,在kubernetes1.14 达到稳固状态。 在这之前,咱们通过设置readiness probe 来决定是否Pod能够开始提供服务--即Pod的地址是否能够呈现在对应endpoints的列表中。然而此时可能相关联的其余根底服务并没有真正准备就绪。 例如,在部署滚动更新期间,一个新的Pod准备就绪。另一方面,因为任何起因(例如api machinery,endpoints controller,kube-proxy,iptables或根底构造编程的速度迟缓),网络策略和负载平衡器尚未为新的pod准备就绪。这可能会导致服务中断或后端容量失落。在极其状况下,如果滚动更新在任何新的替换Pod理论开始为流量提供服务之前实现,则将导致服务中断。 Readiness gates 正是为了解决此类问题呈现的。它给与了Pod之外组件管制Pod 就绪的能力。 Readiness gates取决于Pod的status.condition字段的以后状态。如果Kubernetes在Pod的status.conditions字段中找不到这样的条件,则该条件的状态默认为“ False”。 这是一个例子: kind: Pod...spec: readinessGates: - conditionType: "www.example.com/feature-1"status: conditions: - type: Ready # a built in PodCondition status: "False" lastProbeTime: null lastTransitionTime: 2018-01-01T00:00:00Z - type: "www.example.com/feature-1" # an extra PodCondition status: "False" lastProbeTime: null lastTransitionTime: 2018-01-01T00:00:00Z containerStatuses: - containerID: docker://abcd... ready: true...此时对于应用自定义条件的Pod,仅当以下两个语句均实用时,该Pod才被评估为就绪: Pod中的所有容器均已准备就绪。ReadinessGates中指定的所有条件均为True。当Pod的容器准备就绪,但至多短少一个自定义条件或False时,kubelet将Pod的条件设置为ContainersReady。 如何应用Readiness gates?kubectl patch命令不反对批改对象状态。要为Pod设置这些状态条件,应用程序和operator应用PATCH操作。能够应用Kubernetes客户端库编写代码来设置Pod筹备状态的自定义Pod条件。如何使ReadinessGates对K8s API用户通明。换句话说,K8s API用户无需指定ReadinessGates即可应用特定性能。这容许现有清单仅与须要ReadinessGate的性能一起应用。每个性能都将承当注入ReadinessGate的工作,并放弃其自定义Pod条件放弃同步。能够在容器创立时应用变异的Webhook注入ReadinessGate。Pod创立后,只有其ReadinessGate存在于PodSpec中,每个性能都负责使其自定义Pod条件放弃同步。这能够通过运行k8s控制器来同步相干Pod上的条件来实现。这是为了确保即便在API服务器上产生灾难性故障(例如,数据失落)时,PodStatus也是可察看和可复原的。就地降级和Readiness gates为什么说没有Readiness gates就没有就地降级?原生的Pod降级策略是recreate。一系列的措施保障了Pod在降级过程中,不会服务流量。 ...

July 11, 2020 · 1 min · jiezi

Pod-就地升级1Docker-Image-IDs

前言Docker 镜像是用于创立容器的只读模板,并提供了基于多层文件和门路的有序联结文件系统,该文件系统能够与其余镜像和容器共享。共享镜像层是Docker平台的根本组成部分,并且通过实现写时复制(COW)机制来实现。在其生命周期内,如果容器须要从提供其文件系统的只读映像中更改文件,它将在进行更改之前将文件复制到其本人的公有读写层。 在Docker镜像构建过程中会创立一个层或"diff",并在容器中运行命令时产生的后果,该命令会生成新的或批改的文件和目录。这些新的或批改的文件和目录被“committed”为新的层。 历史的角度历史上(Docker v1.10之前的版本),每次因为'commit'操作而创立新层时,Docker还会创立一个对应的镜像,该镜像由随机生成的256位UUID标识,通常称为镜像ID(在UI中以短12位十六进制字符串或长64位十六进制字符串示意)。 Docker将层内容存储在目录中,该目录的名称与镜像ID雷同。在外部,镜像由配置对象组成,该对象保留镜像的特色,包含其ID和镜像的父镜像的ID。这样,Docker可能为容器构建文件系统,每个镜像顺次援用其父级和相应的层内容,直到达到没有父级的根底镜像为止。每个镜像也能够用有意义的名称标记(例如my_image:1.0),但这通常是为叶子镜像保留的。如下图所示: 应用docker inspect命令: $ docker inspect my_image:1.0[ { "Id": "ca1f5f48ef431c0818d5e8797dfe707557bdc728fe7c3027c75de18f934a3b76", "Parent": "91bac885982d2d564c0e1869e8b8827c435eead714c06d4c670aaae616c1542c" ... ...这种办法能够在继续的一段时间内很好地为Docker服务,然而因为种种原因,随着工夫的推移,这种办法被认为不是最佳的。推动改革的次要能源之一是,短少一种办法来检测图像内容是否在推送或从注册表中拉出时被篡改,例如Docker Hub。这引起了整个社区的强烈批评,并导致了一系列变动,最终造成了内容可寻址的ID。 内容可寻址的IDs从Docker v1.10开始,镜像和镜像层通常不再是同义词。相同,镜像间接援用最终有助于派生容器的文件系统的一层或多层。 当初,通过摘要标识层,摘要的格局为:algorithm:hex;例如: sha256:fc92eec5cac70b0c324cec2933cd7db1c0eae7c9e2649e42d02e77eb6da0d15f十六进制元素是通过将算法(SHA256)利用于镜像层内容来计算的。如果内容更改,则计算的摘要也将更改,这意味着Docker能够应用已公布的摘要查看检索到的层内容,以验证其内容。层没有镜像或属于镜像的概念,它们只是文件和目录的汇合。 Docker镜像当初蕴含一个配置对象,该对象(除其余外)蕴含一个层摘要的有序列表,这使Docker引擎可能参考层摘要而不是父镜像来组装容器的文件系统。镜像ID也是摘要,并且是镜像配置对象的计算得出的SHA256哈希,其中蕴含有助于镜像文件零碎定义的各层的摘要。下图形容了Docker v1.10之后镜像和层之间的关系: 镜像和层的摘要已缩短,以进步可读性。 当初,用于存储层内容的diff目录以一个随机生成的“cache ID”命名,并且Docker引擎保护该层及其cache ID之间的链接,以便它晓得在磁盘上的地位。 因而,当从注册表中提取Docker镜像,并应用docker history命令显示其内容时,输入将提供相似于以下内容: $ docker history swarmIMAGE CREATED CREATED BY SIZE COMMENTc54bba046158 9 days ago /bin/sh -c #(nop) CMD ["--help"] 0 B <missing> 9 days ago /bin/sh -c #(nop) ENTRYPOINT &{["/swarm"]} 0 B <missing> 9 days ago /bin/sh -c #(nop) VOLUME [/.swarm] 0 B <missing> 9 days ago /bin/sh -c #(nop) EXPOSE 2375/tcp 0 B <missing> 9 days ago /bin/sh -c #(nop) ENV SWARM_HOST=:2375 0 B <missing> 9 days ago /bin/sh -c #(nop) COPY dir:b76b2255a3b423981a 0 B <missing> 9 days ago /bin/sh -c #(nop) COPY file:5acf949e76228329d 277.2 kB <missing> 9 days ago /bin/sh -c #(nop) COPY file:a2157cec2320f541a 19.06 MB该命令提供无关镜像及其组成的层的详细信息。 IMAGE字段中除镜像的一层以外的所有<missing>值都具备误导性。它传播了谬误的提醒,然而没有谬误,因为层不再与相应的镜像和ID同义。我认为将字段留空会更适合。同样,镜像ID仿佛与最上层相关联,但实际上,镜像ID不“属于”任何层。而是,这些层独特属于镜像,并提供其文件系统定义。 ...

July 11, 2020 · 2 min · jiezi

从容器监控kubestatsmetrics看k8s众多组件

k8s监控组织架构 指标阐明零碎指标分为节点/容器资源应用和DaemonSet运行的资源服务指标分为Kubernetes根底结构组件产生的和利用pod产生的kube-stats-metrics- job_name: kube-state-metrics honor_timestamps: false scrape_interval: 30s scrape_timeout: 10s metrics_path: /metrics scheme: http static_configs: - targets: - kube-state-metrics.kube-admin:8080k8s apiserver是什么k8s API Server提供了k8s各类资源对象(pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个零碎的数据总线和数据中心 采集原理kube-state-metrics应用client-go与Kubernetes集群通信,一直轮询api-server 初始化metric store family// E:\go_path\src\k8s.io\kube-state-metrics\internal\store\builder.govar availableStores = map[string]func(f *Builder) cache.Store{ "certificatesigningrequests": func(b *Builder) cache.Store { return b.buildCsrStore() }, "configmaps": func(b *Builder) cache.Store { return b.buildConfigMapStore() }, "cronjobs": func(b *Builder) cache.Store { return b.buildCronJobStore() }, "daemonsets": func(b *Builder) cache.Store { return b.buildDaemonSetStore() }, "deployments": func(b *Builder) cache.Store { return b.buildDeploymentStore() }, "endpoints": func(b *Builder) cache.Store { return b.buildEndpointsStore() }, "horizontalpodautoscalers": func(b *Builder) cache.Store { return b.buildHPAStore() }, "ingresses": func(b *Builder) cache.Store { return b.buildIngressStore() }, "jobs": func(b *Builder) cache.Store { return b.buildJobStore() }, "leases": func(b *Builder) cache.Store { return b.buildLeases() }, "limitranges": func(b *Builder) cache.Store { return b.buildLimitRangeStore() }, "mutatingwebhookconfigurations": func(b *Builder) cache.Store { return b.buildMutatingWebhookConfigurationStore() }, "namespaces": func(b *Builder) cache.Store { return b.buildNamespaceStore() }, "networkpolicies": func(b *Builder) cache.Store { return b.buildNetworkPolicyStore() }, "nodes": func(b *Builder) cache.Store { return b.buildNodeStore() }, "persistentvolumeclaims": func(b *Builder) cache.Store { return b.buildPersistentVolumeClaimStore() }, "persistentvolumes": func(b *Builder) cache.Store { return b.buildPersistentVolumeStore() }, "poddisruptionbudgets": func(b *Builder) cache.Store { return b.buildPodDisruptionBudgetStore() }, "pods": func(b *Builder) cache.Store { return b.buildPodStore() }, "replicasets": func(b *Builder) cache.Store { return b.buildReplicaSetStore() }, "replicationcontrollers": func(b *Builder) cache.Store { return b.buildReplicationControllerStore() }, "resourcequotas": func(b *Builder) cache.Store { return b.buildResourceQuotaStore() }, "secrets": func(b *Builder) cache.Store { return b.buildSecretStore() }, "services": func(b *Builder) cache.Store { return b.buildServiceStore() }, "statefulsets": func(b *Builder) cache.Store { return b.buildStatefulSetStore() }, "storageclasses": func(b *Builder) cache.Store { return b.buildStorageClassStore() }, "validatingwebhookconfigurations": func(b *Builder) cache.Store { return b.buildValidatingWebhookConfigurationStore() }, "volumeattachments": func(b *Builder) cache.Store { return b.buildVolumeAttachmentStore() }, "verticalpodautoscalers": func(b *Builder) cache.Store { return b.buildVPAStore() },}初始化watchfunc 接管后果// E:\go_path\src\k8s.io\kube-state-metrics\internal\store\builder.go// reflectorPerNamespace creates a Kubernetes client-go reflector with the given// listWatchFunc for each given namespace and registers it with the given store.func (b *Builder) reflectorPerNamespace( expectedType interface{}, store cache.Store, listWatchFunc func(kubeClient clientset.Interface, ns string) cache.ListerWatcher,) { lwf := func(ns string) cache.ListerWatcher { return listWatchFunc(b.kubeClient, ns) } lw := listwatch.MultiNamespaceListerWatcher(b.namespaces, nil, lwf) instrumentedListWatch := watch.NewInstrumentedListerWatcher(lw, b.metrics, reflect.TypeOf(expectedType).String()) reflector := cache.NewReflector(sharding.NewShardedListWatch(b.shard, b.totalShards, instrumentedListWatch), expectedType, store, 0) go reflector.Run(b.ctx.Done())}指标列举ConfigMap指标: ConfigMap是什么eg: configmap信息kube_configmap_info{configmap="xxx",instance="kube-state-metrics.kube-admin:8080",job="kube-state-metrics",namespace="xxx"}CronJob指标 CronJob是什么eg: cronjob下次调度工夫kube_cronjob_next_schedule_time{cronjob="abc",instance="kube-state-metrics.kube-admin:8080",job="kube-state-metrics",namespace="abc"} 1594306800DaemonSet指标 DaemonSet是什么eg: ready daemonsetkube_daemonset_status_number_ready{daemonset="npd",instance="kube-state-metrics.kube-admin:8080",job="kube-state-metrics",namespace="kube-admin"} 6Deployment Metrics Deployment是什么eg : 不衰弱的podkube_deployment_status_replicas_unavailable{deployment="coredns",instance="kube-state-metrics.kube-admin:8080",job="kube-state-metrics",namespace="kube-system"}Endpoints Metrics : service向其发送流量的对象的IP地址 ...

July 10, 2020 · 2 min · jiezi

邀您参与-阿里巴巴如何扩展-K8s-调度器支持-AI-和大数据任务

简介: 2020 年 7 月 15 日上午 10:00,《阿里巴巴如何扩大 K8s 调度器反对 AI 和大数据工作?》主题线上网络研讨会行将召开。 随着 Kubernetes 的广泛应用,越来越多的开发人员尝试应用 Kubernetes 运行和治理 Web 利用和微服务以外的工作负载。典型场景包含深度学习工作,高性能计算作业,基因计算工作流,甚至是传统的大数据处理工作。 围绕 Kubernetes 容器平台,对立治理各种异构算力资源,高效调度AI、大数据、高性能计算工作,未然成为云原生技术带来改革的畛域之一。 阿里云容器服务团队联合多年 Kubernetes 产品与客户反对教训,基于 Kubernetes scheduling framework 对调度器进行了大量扩大和改良,使其在多种场景下仍然能稳固、高效地调度简单工作负载类型,为用户应用 Kubernetes 同时治理在线利用和离线工作提供了根底技术撑持。 2020 年 7 月 15 日上午 10:00,《阿里巴巴如何扩大 K8s 调度器反对 AI 和大数据工作?》主题线上网络研讨会行将召开。 2020 年 7 月 15 日网研会邀你加入题目:阿里巴巴如何扩大 K8s 调度器反对 AI 和大数据工作?工夫:2020 年 7 月 15 日(10:00 AM)语言:中文 议题介绍本次研讨会将介绍 Kubernetes Scheduling Framework 的倒退现状,以及阿里云 Kubernetes 服务反对调度 AI、大数据等简单工作负载和 GPU 等异构计算资源的实践经验。还将具体介绍如何实现 Coscheduling/Gang Scheduling、Capacity Scheduling 等工作级调度个性。 ...

July 10, 2020 · 1 min · jiezi

详解k8s-4种类型Service

Services 和 PodsKubernetesPods是有生命周期的。他们可以被创建,而且销毁不会再启动。 如果您使用Deployment来运行您的应用程序,则它可以动态创建和销毁 Pod。 一个Kubernetes的Service是一种抽象,它定义了一组Pods的逻辑集合和一个用于访问它们的策略 - 有的时候被称之为微服务。一个Service的目标Pod集合通常是由[Label Selector](https://link.zhihu.com/?target=http%3A//kubernetes.kansea.com/docs/user-guide/labels/%23label-selectors) 来决定的(下面有讲一个没有选择器的Service 有什么用处)。 举个例子,想象一个处理图片的后端运行了三个副本。这些副本都是可以替代的 - 前端不关心它们使用的是哪一个后端。尽管实际组成后端集合的Pod可能会变化,前端的客户端却不需要知道这个变化,也不需要自己有一个列表来记录这些后端服务。Service抽象能让你达到这种解耦。 不像 Pod 的 IP 地址,它实际路由到一个固定的目的地,Service 的 IP 实际上不能通过单个主机来进行应答。 相反,我们使用 iptables(Linux 中的数据包处理逻辑)来定义一个虚拟IP地址(VIP),它可以根据需要透明地进行重定向。 当客户端连接到 VIP 时,它们的流量会自动地传输到一个合适的 Endpoint。 环境变量和 DNS,实际上会根据 Service 的 VIP 和端口来进行填充。 kube-proxy支持三种代理模式: 用户空间,iptables和IPVS;它们各自的操作略有不同。 Userspace作为一个例子,考虑前面提到的图片处理应用程序。 当创建 backend Service 时,Kubernetes master 会给它指派一个虚拟 IP 地址,比如 10.0.0.1。 假设 Service 的端口是 1234,该 Service 会被集群中所有的 kube-proxy 实例观察到。 当代理看到一个新的 Service, 它会打开一个新的端口,建立一个从该 VIP 重定向到新端口的 iptables,并开始接收请求连接。 当一个客户端连接到一个 VIP,iptables 规则开始起作用,它会重定向该数据包到 Service代理 的端口。 Service代理 选择一个 backend,并将客户端的流量代理到 backend 上。 ...

July 8, 2020 · 2 min · jiezi

Kubernetes-攻击矩阵

Kubernetes 攻击矩阵

July 3, 2020 · 1 min · jiezi

使用kubemark进行大规模Kubernetes集群性能测试

使用kubemark进行大规模Kubernetes集群性能测试

July 2, 2020 · 1 min · jiezi

how-to-set-up-kubemark

how to set up kubemark

July 2, 2020 · 1 min · jiezi

Kubernetes探秘配置文件目录结构

Kubernetes探秘—配置文件目录结构

July 2, 2020 · 1 min · jiezi

kubemark模拟k8s计算节点测试k8s组件性能

kubemark模拟k8s计算节点,测试k8s组件性能

July 2, 2020 · 1 min · jiezi

KubernetesK8s-安装使用kubeadm安装Kubernetes集群

Kubernetes(K8s) 安装(使用kubeadm安装Kubernetes集群)

July 1, 2020 · 1 min · jiezi

Kubernetes集群性能测试

Kubernetes集群性能测试

July 1, 2020 · 1 min · jiezi

在Kubernetes上集成Argo工作流和spark

在我的第一篇文章中,我谈到了Argo CD。这次是Argo Workflow,它又来自Argo项目,Kubernetes上的Spark,以及我们如何使两者一起工作。 Argo Workflow Argo Workflow是一个云原生工作流引擎,我们可以在其中编排具有任务序列的作业(工作流中的每个步骤都作为容器)。使用工作流定义,我们可以使用DAG捕获任务之间的依赖关系。替代Airflow?也许会!如果您正在寻找kubernetes的原生产品,我相信Argo Workflow不会让您失望。 将Argo工作流程部署到K8s(请为argo工作流程创建一个名称空间): 1. 安装 helm: curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3chmod 700 get_helm.sh./get_helm.sh2. 增加 argo repo 到 helm 并安装 helm repo add argo https://argoproj.github.io/argo-helmhelm repo updatehelm install argo-wf argo/argo -n argo-wf -f values.yaml在values.yaml中,您可以启用入口(如果集群中有入口控制器可用) ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: “true” hosts: - argo.example.com您将立即部署并运行argo工作流程! Argo中的工作流程自动化由YAML模板驱动。 Argo提供了丰富的文档以及相关示例。如果您正在寻找自动化,我们甚至可以通过REST API提交工作流程。我不会在这里做太多深入的介绍,因为文档详细且经过了很好的解释。让我们继续下一个主题。 Spark on Kubernetes 从Spark 2.3开始,您可以使用Kubernetes运行和管理Spark资源。 Spark可以在Kubernetes管理的集群上运行。此功能使用已添加到Spark的原生Kubernetes调度程序。我们可以按需运行Spark驱动程序和执行程序Pod,这意味着没有专用的Spark集群。 有两种方法可以在Kubernetes上运行Spark:使用Spark-submit和Spark operator。 通过使用spark-submit CLI,您可以使用Kubernetes支持的各种配置选项提交Spark作业。 spark-submit spark-submit将作业提交委托给Kubernetes上的Spark driver pod,最后通过与Kubernetes API服务器通信来创建相关的Kubernetes资源。 ...

June 24, 2020 · 1 min · jiezi

簡單實用的Kubernetes-IDE-Lens

開箱 Lens、K8s IDE、K8s Dashboard,介紹使用在GKE以及Minikube

June 22, 2020 · 1 min · jiezi

Kubernetes集群性能测试

Kubernetes集群性能测试

June 22, 2020 · 1 min · jiezi

比官方K8S-Dashboard好用的桌面客户端Lens

比官方K8S Dashboard好用的桌面客户端:Lens

June 22, 2020 · 1 min · jiezi

Kubernetes中有状态应用的优雅缩容

将有状态的应用程序部署到Kubernetes是棘手的。 StatefulSet使它变得容易得多,但是它们仍然不能解决所有问题。最大的挑战之一是如何缩小StatefulSet而不将数据留在断开连接的PersistentVolume成为孤立对象上。在这篇博客中,我将描述该问题和两种可能的解决方案。 通过StatefulSet创建的每个Pod都有自己的PersistentVolumeClaim(PVC)和PersistentVolume(PV)。当按一个副本按比例缩小StatefulSet的大小时,其Pod之一将终止,但关联的PersistentVolumeClaim和绑定到其的PersistentVolume保持不变。在随后扩大规模时,它们会重新连接到Pod。 Scaling a StatefulSet 现在,想象一下使用StatefulSet部署一个有状态的应用程序,其数据在其pod中进行分区。每个实例仅保存和处理一部分数据。当您缩小有状态应用的规模时,其中一个实例将终止,其数据应重新分配到其余的Pod。如果您不重新分配数据,则在再次进行扩展之前,它仍然不可访问。 Redistributing data on scale-down 在正常关机期间重新分发数据您可能会想:“既然Kubernetes支持Pod正常关闭的机制,那么Pod是否可以在关闭过程中简单地将其数据重新分配给其他实例呢?”事实上,它不能。为什么不这样做有两个原因: Pod(或更确切地说,其容器)可能会收到除缩容以外的其他原因的终止信号。容器中运行的应用程序不知道为什么终止该程序,因此不知道是否要清空数据。即使该应用程序可以区分是缩容还是由于其他原因而终止,它也需要保证即使经过数小时或数天也可以完成关闭程序。 Kubernetes不提供该保证。如果应用程序进程在关闭过程中死掉,它将不会重新启动,因此也就没有机会完全分发数据。因此,相信在正常关闭期间Pod能够重新分发(或以其他方式处理其所有数据)并不是一个好主意,并且会导致系统非常脆弱。 使用 tear-down 容器?如果您不是Kubernetes的新手,那么你很可能知道什么是初始化容器。它们在容器的主要容器之前运行,并且必须在主要容器启动之前全部完成。 如果我们有tear-down容器(类似于init容器),但是在Pod的主容器终止后又会运行,该怎么办?他们可以在我们的有状态Pod中执行数据重新分发吗? 假设tear-down容器能够确定Pod是否由于缩容而终止。并假设Kubernetes(更具体地说是Kubelet)将确保tear-down容器成功完成(通过在每次返回非零退出代码时重新启动它)。如果这两个假设都成立,我们将拥有一种机制,可确保有状态的容器始终能够按比例缩小规模重新分配其数据。 但是? 可悲的是,当tear-down容器本身发生瞬态错误,并且一次或多次重新启动容器最终使它成功完成时,像上述的tear-down容器机制将只处理那些情况。但是,在tear-down过程中托管Pod的集群节点死掉的那些不幸时刻又如何呢?显然,该过程无法完成,因此无法访问数据。 现在很明显,我们不应该在Pod关闭时执行数据重新分配。相反,我们应该创建一个新的Pod(可能安排在一个完全不同的集群节点上)以执行重新分发过程。 这为我们带来了以下解决方案: 缩小StatefulSet时,必须创建一个新的容器并将其绑定到孤立的PersistentVolumeClaim。我们称其为“_drain pod_”,因为它的工作是将数据重新分发到其他地方(或以其他方式处理)。Pod必须有权访问孤立的数据,并且可以使用它做任何想做的事情。由于每个应用程序的重新分发程序差异很大,因此新的容器应该是完全可配置的-用户应该能够在drain Pod内运行他们想要的任何容器。 StatefulSet Drain Controller由于StatefulSet控制器当前尚不提供此功能,因此我们可以实现一个额外的控制器,其唯一目的是处理StatefulSet缩容。我最近实现了这种控制器的概念验证。您可以在GitHub上找到源代码: luksa/statefulset-scaledown-controllergithub.com 下面我们解释一下它是如何工作的。 在将控制器部署到Kubernetes集群后,您只需在StatefulSet清单中添加注释,即可将drain容器模板添加到任何StatefulSet中。这是一个例子: apiVersion: apps/v1kind: StatefulSetmetadata: name: datastore annotations: statefulsets.kubernetes.io/drainer-pod-template: | { "metadata": { "labels": { "app": "datastore-drainer" } }, "spec": { "containers": [ { "name": "drainer", "image": "my-drain-container", "volumeMounts": [ { "name": "data", "mountPath": "/var/data" } ] } ] } }spec: ...该模板与StatefulSet中的主要Pod模板没有太大区别,只不过它是通过注释定义的。您可以像平常一样部署和扩展StatefulSet。 ...

June 22, 2020 · 1 min · jiezi

延迟应用启动直到Sidecar准备就绪

Kubernetes在Pod中启动容器的方式出乎意料。在检查了源代码以确认我所看到的内容之后,我意识到我刚刚找到了Istio Service Mesh中一个长期存在的问题的解决方案。 我相信大多数Kubernetes用户都假定Pod的初始化容器完成后,将并行启动Pod的常规容器。事实并非如此。 如果检查启动容器的Kubelet代码,则会注意到它是按顺序执行的。该代码在一个线程中执行,并按照容器在pod的spec.containers数组中列出的顺序启动容器。 // Step 7: start containers in podContainerChanges.ContainersToStart. for _, idx := range podContainerChanges.ContainersToStart { start("container", containerStartSpec(&pod.Spec.Containers[idx])) }但是,假设容器镜像已经存储在本地,则在Kubelet启动第一个容器之后,Kubelet启动第二个容器所花费的时间可以忽略不计。实际上,它们都是同时启动的。 当一个容器依赖于另一个容器并要求它完全启动才能运行时,这是不理想的。 Istio Proxy sidecar容器就是一个例子。由于应用程序的传出通信是通过代理路由的,因此在启动应用程序本身之前,代理必须已启动并正在运行。 您可以在应用程序容器中添加一个Shell脚本,以等待代理启动,然后运行该应用程序的可执行文件。但这需要更改应用程序本身。理想情况下,我们希望在不对应用程序或其容器镜像进行任何更改的情况下将代理注入Pod。 事实证明,这可以通过利用Kubernetes中的同步容器启动来完成。 首先,我们需要将代理指定为spec.containers中的第一个容器,但这只是解决方案的一部分,因为它只能确保首先启动代理容器,而不会等待其准备就绪。其他容器立即启动,从而导致容器之间的竞争状态。我们需要防止Kubelet在代理准备好之前启动其他容器。 这是启动后生命周期钩子出现的地方。事实证明,启动容器的Kubelet代码会阻止下一个容器的启动,直到启动后处理程序终止为止。 我们可以利用这种行为。不仅在Istio中,而且在必须启动Sidecar容器并准备就绪的每个Pod中,应用程序容器才能启动。 简而言之,Sidecar启动问题的解决方案如下: 如果sidecar容器提供了一个等待该sidecar就绪的可执行文件,则可以在容器的启动后挂钩中调用该文件,以阻止pod中其余容器的启动。 下图应该可以帮助您直观地看到容器中发生的情况。 具体yaml如下: apiVersion: v1kind: Podmetadata: name: sidecar-starts-firstspec: containers: - name: sidecar image: my-sidecar lifecycle: postStart: exec: command: - /bin/wait-until-ready.sh - name: application image: my-application但是,这种方法并不完美。如果在启动后挂钩中调用的命令或容器的主进程失败,则其他容器将立即启动。尽管如此,在Kubernetes引入对sidecar container的适当支持之前,这应该是一个好的解决方法。或者直到有人决定更改Kubelet的行为,并使其在单独的goroutine中启动容器。 尽管此技术可以解决容器启动顺序的问题,但是当您删除容器时,容器的容器停止顺序却无济于事。Pod的容器实际上是并行终止的。当它关闭一个Pod时,Kubelet在goroutine中执行容器终止代码-每个容器一个。与启动后挂钩不同,停止前挂钩因此并行运行。 如果仅在主应用程序容器终止后才需要停靠sidecar,则必须以其他方式处理。 PS: 本文属于翻译,原文

June 21, 2020 · 1 min · jiezi

k8s-部署生产vault集群

在之前的文章中,我们在k8s中部署了consul 生产集群。今天我继续在k8s中部署一个vault的生产集群。 Vault可以在高可用性(HA)模式下运行,以通过运行多个Vault服务器来防止中断。Vault通常受存储后端的IO限制的约束,而不是受计算要求的约束。某些存储后端(例如Consul)提供了附加的协调功能,使Vault可以在HA配置中运行,而其他一些则提供了更强大的备份和还原过程。 在高可用性模式下运行时,Vault服务器具有两个附加状态:备用和活动状态。在Vault群集中,只有一个实例将处于活动状态并处理所有请求(读取和写入),并且所有备用节点都将请求重定向到活动节点。 部署 我们的consul 集群复用之前文章中部署的consul集群。 vault配置文件server.hcl如下: listener "tcp" { address = "0.0.0.0:8200" cluster_address = "POD_IP:8201" tls_disable = "true"}storage "consul" { address = "127.0.0.1:8500" path = "vault/"}api_addr = "http://POD_IP:8200"cluster_addr = "https://POD_IP:8201"接下我们创建configmap: kubectl create configmap vault --from-file=server.hcl大家可以注意到配置文件中的POD_IP,我们将会在容器启动的时候,sed替换成真实的pod的IP。我们采用StatefulSet方式部署一个两个节点的vault集群。通过sidecar的方式将consul client agent和vault部署到一个Pod中。 apiVersion: apps/v1kind: StatefulSetmetadata: name: vault labels: app: vaultspec: serviceName: vault podManagementPolicy: Parallel replicas: 3 updateStrategy: type: OnDelete selector: matchLabels: app: vault template: metadata: labels: app: vault spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - consul topologyKey: kubernetes.io/hostname podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - vault topologyKey: kubernetes.io/hostname containers: - name: vault command: - "/bin/sh" - "-ec" args: - | sed -E "s/POD_IP/${POD_IP?}/g" /vault/config/server.hcl > /tmp/server.hcl; /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/server.hcl image: "vault:1.4.2" imagePullPolicy: IfNotPresent securityContext: capabilities: add: - IPC_LOCK env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: VAULT_ADDR value: "http://127.0.0.1:8200" - name: VAULT_API_ADDR value: "http://$(POD_IP):8200" - name: SKIP_CHOWN value: "true" volumeMounts: - name: vault-config mountPath: /vault/config/server.hcl subPath: server.hcl ports: - containerPort: 8200 name: vault-port protocol: TCP - containerPort: 8201 name: cluster-port protocol: TCP readinessProbe: # Check status; unsealed vault servers return 0 # The exit code reflects the seal status: # 0 - unsealed # 1 - error # 2 - sealed exec: command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"] failureThreshold: 2 initialDelaySeconds: 5 periodSeconds: 3 successThreshold: 1 timeoutSeconds: 5 lifecycle: # Vault container doesn't receive SIGTERM from Kubernetes # and after the grace period ends, Kube sends SIGKILL. This # causes issues with graceful shutdowns such as deregistering itself # from Consul (zombie services). preStop: exec: command: [ "/bin/sh", "-c", # Adding a sleep here to give the pod eviction a # chance to propagate, so requests will not be made # to this pod while it's terminating "sleep 5 && kill -SIGTERM $(pidof vault)", ] - name: consul-client image: consul:1.7.4 env: - name: GOSSIP_ENCRYPTION_KEY valueFrom: secretKeyRef: name: consul key: gossip-encryption-key - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP args: - "agent" - "-advertise=$(POD_IP)" - "-config-file=/etc/consul/config/client.json" - "-encrypt=$(GOSSIP_ENCRYPTION_KEY)" volumeMounts: - name: consul-config mountPath: /etc/consul/config - name: consul-tls mountPath: /etc/tls lifecycle: preStop: exec: command: - /bin/sh - -c volumes: - name: vault-config configMap: defaultMode: 420 name: vault - name: consul-config configMap: defaultMode: 420 name: consul-client - name: consul-tls secret: secretName: consul如果你的k8s集群pod网段flat,可以和vpc当中的主机互相访问。那么按照以上的配置即可。否则需要设置pod的hostNetwork: true。查看部署情况: ...

June 21, 2020 · 4 min · jiezi

为什么k8s被叫做容器编排器

先吐槽一下: sf的编辑器好奇怪,对yaml代码的md支持不好。我放弃了,斗不过sf的这个代码编辑器。。。看来文章和评论的编辑器一样,同样对yaml支持不友好不能说是docker的编排工具,应该说是对“容器”的编排工具,docker只是一种容器实现方式 “编排”,通俗理解,类似我国以前大学生毕业后工作“包分配”,大学生毕业后,根据事业单位的特点和大学生的专业和特长信息,看看他们应该安排到哪个单位合适。 一般我们一个集群的会有“多台物理机器”,每个物理机器又可以跑“多个容器”,但是到底哪个容器应该跑在哪些物理机里面,就要有一套规则规划,k8s就是实现了这样一套规则。 简单举个几个例子,k8s的这些规则里面有比如“节点选择”,“节点亲和性”、“pod亲和性”等 节点选择比如下面这个这个规则,我们希望nginx安排跑在有ssd类型硬盘的物理机器上 apiVersion: v1kind: Podmetadata: name: nginx labels: env: testspec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: disktype: ssd节点亲和性如下面这个例子,我们希望: 比如 192.168.1.140和 192.168.1.161 不要给我跑pod,area=south如的这个果有节点满足area=south的这个条件的话,pod尽量往这里安排。 apiVersion: v1kind: Pod...spec: containers: name: with-node-affinity image: nginxaffinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - 192.168.1.140 - 192.168.1.161 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: area operator: In values: - south# pod亲和性如下面这例子,我们希望:1. 我们希望这个pod和有`app=busybox-pod`这个标签信息的pod,尽量分配到一起2. 同时,不希望这个pod和有`app=node-affinity-pod`的这些pod尽量不要搞到一起。apiVersion: v1kind: Pod...spec: containers: ...

June 20, 2020 · 1 min · jiezi

使用水平Pod自动缩放器在Kubernetes上自动缩放应用程序

本文概述了Kubernetes中的Horizontal Pod Autoscaler(HPA)的工作方式以及使用方法。 介绍部署具有静态配置的副本数的无状态应用不是最佳选择。 而弹性副本数目具备以下特点: 当请求率增加时,应用程序应扩大规模(即增加副本数)以保持响应速度。当请求率降低时,应用程序应缩小规模(即减少副本数),以避免浪费资源。在水平缩放的情况下,放大也称为“_scaling out_”,而缩小也称为“_scaling in_”。这与垂直缩放(请参见下文)形成对比,垂直缩放仅使用术语“按比例放大”和“按比例缩小”。借助Horizontal Pod Autoscaler(HPA),Kubernetes以上述方式为自动缩放应用程序提供了出色的支持。 Kubernetes中不同类型的自动伸缩首先,为消除任何误解,让我们澄清一下Kubernetes中术语“自动缩放”的用法。 Kubernetes包括几个自动缩放功能: Horizontal Pod Autoscaler (HPA): 调整应用程序副本Pod的数量(水平缩放)Vertical Pod Autoscaler (VPA): 调整资源请求和应用程序容器的限制(垂直缩放)Cluster Autoscaler: 调整集群的节点数这些自动缩放器彼此完全独立,并且都使用不同的概念和机制。 本文专门讨论Horizontal Pod Autoscaler。 什么是Horizontal Pod Autoscaler?Horizontal Pod Autoscaler(HPA)是内置的Kubernetes功能,它允许根据一个或多个默认或用户定义的指标来水平缩放应用程序。 水平缩放意味着增加和减少副本数量。垂直缩放意味着增加和减少单个副本的计算资源。从技术上讲,HPA是一个Kubernetes控制器,用于跟踪HorizontalPodAutoscaler资源并由其配置。 HPA持续监视有关一个应用程序的一个或多个指标,并调整此应用程序的副本数,以使指标尽可能接近指定的目标值。 HPA可以使用scale子资源来扩展所有这些Kubernetes资源,其中包括Deployment,StatefulSet和ReplicaSet。HPA执行的控制循环如下所示: 控制循环的步骤为: 查询缩放指标计算所需的副本数将应用程序缩放到所需数量的副本默认情况下,此控制循环每15秒执行一次。所需副本数的计算基于缩放指标和这些指标的用户提供的目标值。 在控制循环的每次迭代中,HPA都会计算出一个副本计数,该副本计数将使度量的测量值尽可能接近目标值。 例如,假设缩放指标是应用程序所有副本Pod每秒平均接收的请求数(req/sec): 如果目标值为10 req / sec,当前值为20 req / sec,则应用程序过载,并且HPA必须扩大应用程序的规模(即增加副本数),以使度量标准减小并接近目标值。如果目标值为10 req / sec,当前值为2 req / sec,则该应用程序未充分利用,因此HPA必须缩小该应用程序的比例(即减少副本数),以使度量标准提高并更加接近目标值。用于计算所需副本数的算法基于以下公式: X = N * (c/t)解读: X 是期望的副本数N 是当前的副本数c 伸缩指标的当前值t 伸缩指标的目前值这就是HPA的总体运作方式-现在让我们看一下它的配置方式。 如何配置Horizontal Pod Autoscaler?通过HorizontalPodAutoscaler资源完成HPA的配置。 HorizontalPodAutoscaler资源可以指定以下信息: ...

June 18, 2020 · 1 min · jiezi

分享一份阿里云内部超全K8s实战手册免费下载

一直关注云计算领域的人,必定知道Docker和Kubernetes的崛起。如今,世界范围内的公有云巨头(谷歌、亚马逊、微软、华为云、阿里云等等)都在其传统的公共云服务之上提供托管的Kubernetes服务。Kubernetes功能强大、扩展性高,在许多人看来,它正在成为云计算的终极解决方案。 接下来本文将为大家免费提供阿里云《深入浅出Kubernetes项目实战手册》下载,帮助你一次搞懂 6 个核心原理,吃透基础理论,一次学会 6 个典型问题的华丽操作! 如何免费下载 扫码,发送"阿里云",即可免费获得 ▲持续关注 获取更多免费福利 理论和实践的完美契合 技术细节追根究底 阿里云真实案例的沉淀 理论阐述深入浅出 本书作者罗建龙(花名声东),阿里云技术专家,有着多年操作系统和图形显卡驱动调试和开发经验。目前专注云原生领域,容器集群和服务网格。本书分为理论篇和实践篇,共汇集了 12 篇技术文章,深入解析了集群控制、集群伸缩原理、镜像拉取等理论,带你实现从基础概念的准确理解到上手实操的精准熟练,深入浅出使用 Kubernetes!

June 18, 2020 · 1 min · jiezi

使用Open-Policy-Agent实现Kubernetes-Pod安全策略

Kubernetes是当今云原生生态系统中最受欢迎的容器编排平台。因此,Kubernetes的安全性也引起了越来越多的关注。 在此博客文章中,首先我将讨论Pod安全策略准入控制器。然后,我们将看到Open Policy Agent如何实现Pod安全策略。实际上,Open Policy Agent被视为Pod安全策略的潜在替代方案。 首先,简要介绍一下容器,安全性和准入控制器。 容器和安全简介容器轻巧,轻便且易于管理。在同一主机上运行的容器没有单独的物理/虚拟机。换句话说,容器共享运行它们的主机的资源,硬件和OS内核。因此,具有适当的安全性变得非常重要,这些安全性涉及容器中可以运行哪些进程,这些进程具有哪些特权,容器是否将允许特权升级,使用了什么镜像等等。 Pod是Kubernetes应用程序的基本执行单元,是您创建或部署的Kubernetes对象模型中最小和最简单的单元。它是一个或多个具有共享存储/网络的容器的组,以及有关如何运行容器的规范。因此,在容器上实施安全策略时,我们将检查安全策略并将其应用于Pod规范。那么,这些策略如何执行?使用准入控制器。 什么是Admission Controllers?准入控制器是kube-apiserver的一部分。在配置存储在集群设置(etcd)中之前,它们拦截对Kubernetes API服务器的请求。准入控制器可以是正在验证(用于验证传入请求的一个)或正在变异(用于修改传入请求的一个)或两者都在进行。请参阅Kubernetes文档以快速浏览各种准入控制器。 Open Policy Agent 作为 admission controllerOpen Policy Agent(OPA)是一种开放源代码的通用策略引擎,可以将策略编写为代码。 OPA提供了一种高级声明性语言-Rego-以策略作为代码。使用OPA,我们可以跨微服务,CI / CD管道,API网关等执行策略。 OPA最重要的用例之一是Kubernetes作为准入控制者的策略实施。 OPA作为准入控制器,您可以强制执行非root用户之类的策略,要求使用特定的资源标签,确保所有pod都指定了资源请求和限制等。基本上,OPA允许您使用Rego语言将任何自定义策略编写为代码。 这些策略以Rego编写并加载到OPA中,作为Kubernetes集群上的准入控制器运行。 OPA将根据Rego策略评估对Kubernetes API服务器的任何资源创建/更新/删除请求。如果请求满足所有策略,则允许该请求。但是,即使单个策略失败,请求也会被拒绝。 在此处阅读有关OPA,Rego的更多信息,并用作OPA文档中的准入控制器。 Pod Security PolicyPod安全策略(PSP)是实现为准入控制器的集群级别资源。 PSP允许用户将安全要求转换为管理Pod规范的特定策略。首先,创建PodSecurityPolicy资源时,它什么也不做。为了使用它,必须通过允许“使用”动词来授权请求用户或目标pod的服务帐户使用该策略。您可以参考Kubernetes文档上的启用Pod安全策略。 注意,PSP准入控制器既充当验证角色,又充当变异准入控制器。对于某些参数,PSP准入控制器使用默认值来更改传入的请求。此外,顺序始终是先突变然后验证。 使用PSP我们可以控制哪些所有参数?下表简要概述了PSP中使用的各种参数和字段。在此处的Kubernetes文档中提供了详细说明。 那么,我们可以在OPA中实现PSP吗?前面提到,Rego语言允许我们将任何自定义策略编写为代码。这意味着,我们可以使用Rego编写上述的Pod安全策略,并以OPA作为准入控制器来执行。 让我们快速了解一下实施“特权”Pod安全策略的Rego策略。可以在Rego playground试用此策略。 package kubernetes.admissiondeny[message] { #applies for Pod resources input.request.kind.kind == "Pod" #loops through all containers in the request container := input.request.object.spec.containers[_] #for each container, check privileged field container.securityContext.privileged #if all above statements are true, return message message := sprintf("Container %v runs in privileged mode.", [container.name])}那么,该策略有何作用?如果输入请求中的任何容器正在作为特权容器运行,它将返回一条消息。 ...

June 10, 2020 · 1 min · jiezi

Linkerd-28简单安全的多集群Kubernetes服务网格

我们很高兴宣布Linkerd 2.8的发布!该版本为Linkerd引入了一个新的多集群扩展,使它可以跨Kubernetes集群建立连接,这些集群对应用程序而言是安全的,透明的,并且可以与任何网络拓扑一起使用。我们认为,这是当今提供安全的Kubernetes多集群连接的最简单选择。 2.8版本还使Linkerd在附加系统的开头有了更多的模块化,并引入了许多其他功能和稳定性改进。 Multi-cluster KubernetesLinkerd 2.8的新多集群功能意味着Linkerd现在可以安全,对应用程序完全透明且独立于网络拓扑的方式跨集群边界连接Kubernetes服务。正如我们之前的文章中所讨论的,此多集群功能旨在满足一些关键目标: 提供统一的信任域。源工作负载和目标工作负载的身份必须在群集边界内和跨群集边界的每一步进行验证。分离故障域。群集中断仍应允许其余群集正常运行。支持异构网络。由于群集可以跨越云,VPC,本地数据中心及其组合,因此Linkerd除网关连接性外,不应引入任何L3 / L4要求。提供具有集群内通信的统一模型。 Linkerd为群集内通信提供的可观察性,可靠性和安全性功能应扩展到这种新的跨群集通信。就像集群内连接一样,Linkerd的跨集群连接对应用程序代码也是透明的。cluster _west_的服务A可以通过直接将其寻址为C.east或将其寻址为C并让Linkerd自动将该服务的流量路由(甚至转移一部分)到集群C,以与集群C的服务C对话。东向集群。不管该通信是在集群内,在数据中心或VPC内的跨集群还是在公共Internet上进行,Linkerd都将在集群之间建立连接,并通过mTLS在两侧进行加密和认证。 这项新的多集群功能可为Linkerd解锁大量用例,包括故障转移(在出现故障时跨数据中心或云转换流量); “反向多租户”(每个租户都有自己的集群);混合云(工作负载可以在本地环境和云环境之间移动,而不会影响应用程序的其余部分)。 最后,像Linkerd的所有功能一样,Linkerd的多集群“服务镜像”方法会尽可能利用现有的Kubernetes功能,并最少增加额外的设备。远程服务直接表示为Kubernetes服务;没有引入新的CRD;并且配置复杂度保持在最低限度。 Ambassador 支持 Multi-cluster我们很高兴地报告,我们在Ambassador项目中的朋友已经创建了一个多集群集成,使Ambassador用户可以利用Ambassador部署作为Linkerd的多集群网关!在Ambassador博客文章中了解更多信息。 附加组件2.8版本还引入了一个简单的附加系统,用于从Linkerd添加(或删除)功能包。 Linkerd 2.8附带两个插件: 一个Jaeger插件,它添加Jaeger和oc-collector组件以收集和显示分布式跟踪到您的集群一个Grafana插件(默认情况下启用),可将Grafana图添加到Linkerd的仪表板。将来,我们将把更多功能转移到附加组件中,例如,您可以删除默认的Prometheus安装,然后用自己的安装替换,也可能完全不用。 其他Linkerd 2.8还提供了大量其他改进,性能增强和错误修复的列表,其中包括: Helm图表更加灵活和模块化,带有新的Prometheus配置选项。代理现在使用pod元数据标记发出的分布式跟踪范围。代理的各种性能改进,以减少争用,改善延迟并减少虚假超时。自动防止常见的流量环流情况。有关详细信息,请参见完整的发行说明。 Linkerd的规划我们相信Linkerd的核心价值是连通性-在云原生世界中,连通性不仅仅意味着“ A和B可以交换数据包”,而是“ A和B可以以验证双方身份的方式交换数据包”侧面具有清晰的授权语义;对第三方保密;并且是可测量和可检查的”。 展望未来,我们看到Linkerd能够创建此连接,从而将其转换为适用于您的Kubernetes下文的安全平面。 2.8版本标志着朝着这个方向迈出了一大步,接下来的几个版本将充实Linkerd的功能集,包括将mTLS扩展到所有连接。引进政策;以及更多。请继续关注有关此主题的更多信息。 立即体验准备尝试Linkerd了吗?那些通过我们每周的边缘发布跟踪2.x分支的人将已经看到这些功能的实际应用。无论哪种方式,都可以通过运行以下命令下载稳定的2.8版本: curl https://run.linkerd.io/install | sh使用Helm?请参阅我们的有关在Helm中安装Linkerd的指南。从以前的版本升级?我们为您提供了覆盖:请参阅我们的Linkerd升级指南,以了解如何使用linkerd upgrade命令。 PS:本文属于翻译,原文

June 10, 2020 · 1 min · jiezi

Consul-on-Kubernetes

consul 发展到今日,早已不是只用于服务发现和配置共享的工具了。官方对其的定义是自动化网络配置,发现服务并启用跨任何云或运行时的安全连接。 特性与Kubernetes集成和扩展。利用Helm在Kubernetes上快速部署Consul。自动为Kubernetes资源注入sidecar。将多个集群联合到一个服务网格中。跨任何运行时的服务网格。在任何运行时或基础架构中跨任何云在裸机,虚拟机和Kubernetes集群中部署服务网格。 动态的负载均衡。通过集成的DNS解决发现的服务。自动化第三方负载均衡器(F5,NGINX,HAProxy)。无需手动配置网络设备。安全的多云服务网络。利用访问策略和服务网格资源之间的自动mTLS加密,在任何环境中运行的安全服务。 通过运行状况检查发现服务。Consul支持检测新服务的部署,对现有服务的更改,并提供实时代理运行状况以减少停机时间。强大的生态系统。Consul为许多流行的DevOps和网络工具提供支持并与之集成。默认端口consul 默认使用下列端口 8300(tcp): Server RPC,server 用于接受其他 agent 的请求8301(tcp,udp): Serf LAN,数据中心内 gossip 交换数据用8302(tcp,udp): Serf WAN,跨数据中心 gossip 交换数据用8400(tcp): CLI RPC,接受命令行的 RPC 调用8500(tcp): HTTP API 及 Web UI8600(tcp udp): DNS 服务,可以把它配置到 53 端口来响应 dns 请求部署官方推荐的helm部署方案,包括了诸多解决方案。当我们只是用来做服务发现或是配置中心的时候,我们可以选择yaml部署。 本文将完成在Kubernetes上部署三(3)节点Consul集群。 使用StatefulSet的三(3)个节点Consul群集使用TLS和加密密钥的Consul成员之间的安全通信生成 TLS Certificates新建ca目录,包含以下三个文件: ca-config.json { "signing": { "default": { "expiry": "43800h" }, "profiles": { "default": { "usages": ["signing", "key encipherment", "server auth", "client auth"], "expiry": "43800h" } } }}ca-csr.json ...

June 10, 2020 · 3 min · jiezi

记一次-K8S-内部服务调用域名解析超时排坑经历

前言近期线上 k8s 时不时就会出现一些内部服务间的调用超时问题,通过日志可以得知超时的原因都是出现在域名解析上,并且都是 k8s 内部的域名解析超时,于是直接先将内部域名替换成 k8s service 的 IP,观察一段时间发现没有超时的情况发生了,但是由于使用 service IP 不是长久之计,所以还要去找解决办法。 复现一开始运维同事在调用方 pod 中使用ab工具对目标服务进行了多次压测,并没有发现有超时的请求,我介入之后分析ab这类 http 压测工具应该都会有 dns 缓存,而我们主要是要测试 dns 服务的性能,于是直接动手撸了一个压测工具只做域名解析,代码如下: package mainimport ( "context" "flag" "fmt" "net" "sync/atomic" "time")var host stringvar connections intvar duration int64var limit int64var timeoutCount int64func main() { // os.Args = append(os.Args, "-host", "www.baidu.com", "-c", "200", "-d", "30", "-l", "5000") flag.StringVar(&host, "host", "", "Resolve host") flag.IntVar(&connections, "c", 100, "Connections") flag.Int64Var(&duration, "d", 0, "Duration(s)") flag.Int64Var(&limit, "l", 0, "Limit(ms)") flag.Parse() var count int64 = 0 var errCount int64 = 0 pool := make(chan interface{}, connections) exit := make(chan bool) var ( min int64 = 0 max int64 = 0 sum int64 = 0 ) go func() { time.Sleep(time.Second * time.Duration(duration)) exit <- true }()endD: for { select { case pool <- nil: go func() { defer func() { <-pool }() resolver := &net.Resolver{} now := time.Now() _, err := resolver.LookupIPAddr(context.Background(), host) use := time.Since(now).Nanoseconds() / int64(time.Millisecond) if min == 0 || use < min { min = use } if use > max { max = use } sum += use if limit > 0 && use >= limit { timeoutCount++ } atomic.AddInt64(&count, 1) if err != nil { fmt.Println(err.Error()) atomic.AddInt64(&errCount, 1) } }() case <-exit: break endD } } fmt.Printf("request count:%d\nerror count:%d\n", count, errCount) fmt.Printf("request time:min(%dms) max(%dms) avg(%dms) timeout(%dn)\n", min, max, sum/count, timeoutCount)}编译好二进制程序直接丢到对应的 pod 容器中进行压测: ...

June 9, 2020 · 5 min · jiezi

细数k8s支持的4种类型的container

截止目前k8s1.18,k8s已经支持标准容器,sidecar容器,init 容器,ephemeral 容器 4种类型的containers。本文我们详细介绍一下这4种容器的特性已经使用场景。 Ephemeral 容器临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 ContainerSpec 段进行描述,但许多字段是不相容且不允许的。 临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。Pod 资源分配是不可变的,因此 resources 配置是不允许的。有关允许字段的完整列表,请参见临时容器参考文档。临时容器是使用 API 中的一种特殊的 ephemeralcontainers 处理器进行创建的,而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器。 与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。 为什么我们需要Ephemeral 容器? 我们知道容器的优点是它们通过使用不变方法提供所有必需的依赖项来运行隔离的进程。通过仅将所需的依赖项添加到镜像中,容器可以降低攻击面并提供更快的启动和部署。使用“distroless”方法构建容器镜像(基于scratch),通过仅包含已编译的应用程序二进制文件,将容器镜像提升到了一个新的水平。与普通的容器镜像不同,它们不基于任何种类的Linux发行版,因此不包含任何其他可通过kubectl exec执行以进行故障排除的二进制文件和工具。这就决定了该容器有助于提供安全可靠的运行时环境,但也很难在问题发生时进行调试。 在这种情况下,临时容器发挥作用。它们实现了调试容器附加到主进程的功能,然后你可以用于调试任何类型的问题。调试容器可以基于任何镜像,因此可以根据您的需求进行定制。您可以构建自己的调试镜像,其中包含特殊的调试二进制文件或仅包含curl,OpenSSL和MongoDB客户端之类的工具。但是,您也可以选择Linux发行版(如Ubuntu)或仅运行Busybox镜像,这两个镜像都已经包含了许多有用的工具。 如何使用临时容器? 临时容器是alpha功能,因此默认情况下处于禁用状态。您将需要激活以下功能门才能使用它们: 临时容器PodShareProcessNamespace(v1.16中的beta版,因此默认情况下已启用)本节中的示例演示了临时容器如何出现在 API 中。 通常,您可以使用 kubectl 插件进行故障排查,从而自动化执行这些步骤。 临时容器是使用 Pod 的 ephemeralcontainers 子资源创建的,可以使用 kubectl --raw 命令进行显示。首先描述临时容器被添加为一个 EphemeralContainers 列表: { "apiVersion": "v1", "kind": "EphemeralContainers", "metadata": { "name": "example-pod" }, "ephemeralContainers": [{ "command": [ "sh" ], "image": "busybox", "imagePullPolicy": "IfNotPresent", "name": "debugger", "stdin": true, "tty": true, "terminationMessagePolicy": "File" }]}使用如下命令更新已运行的临时容器 example-pod: ...

June 7, 2020 · 2 min · jiezi

Kubernetes本地持久化方案

Kubernetes中的本地存储意味着在每个节点服务器上本地可用的存储设备或文件系统。本文介绍Kubernetes中现有的本地存储解决方案,包括官方原生支持的存储方式以及社区的一些常见方案。 目前官方支持以下3种本地存储方式: emptyDirhostPathLocal Persistent VolumeemptyDir当 Pod 指定到某个节点上时,首先创建的是一个emptyDir卷,并且只要 Pod 在该节点上运行,卷就一直存在。 就像它的名称表示的那样,卷最初是空的。 尽管 Pod 中的容器挂载emptyDir卷的路径可能相同也可能不同,但是这些容器都可以读写emptyDir卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir卷中的数据也会永久删除。 注意:容器崩溃并不会导致 Pod 被从节点上移除,因此容器崩溃时 `emptyDir` 卷中的数据是安全的。emptyDir 的一些用途: 缓存空间,例如基于磁盘的归并排序。为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。默认情况下, emptyDir 卷存储在支持该节点所使用的介质上;这里的介质可以是磁盘或 SSD 或网络存储,这取决于您的环境。 但是,您可以将 emptyDir.medium 字段设置为 "Memory",以告诉 Kubernetes 为您安装 tmpfs(基于 RAM 的文件系统)。 虽然 tmpfs 速度非常快,但是要注意它与磁盘不同。 tmpfs 在节点重启时会被清除,并且您所写入的所有文件都会计入容器的内存消耗,受容器内存限制约束。 emptyDir的位置应该在运行pod的给定节点上的/var/lib/kubelet/pods/{podid}/volumes/kubernetes.io~empty-dir/ 目录下。 Pod 示例apiVersion: v1kind: Podmetadata: name: my-podspec: containers: - image: my-app-image name: my-app volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {}Pod中的所有容器共享使用emptyDir卷。因此,我们使用emptyDir的一个场景是,Pod中init容器负责到配置中心或是秘钥管理中心拉取一些配置,然后写入到emptyDir中,这样业务容器就可以读取到配置。hostPathhostPath卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中。 虽然这不是大多数 Pod 需要的,但是它为一些应用程序提供了强大的逃逸机会。 ...

June 7, 2020 · 2 min · jiezi

Pod多网卡方案MULTUS

在Kubernetes中,网络是非常重要的一个领域。 Kubernetes本身不提供网络解决方案,但是提供了CNI规范。这些规范被许多CNI插件(例如WeaveNet,Flannel,Calico等)遵守。这些插件中任何一个都可以在集群上使用和部署以提供网络解决方案。该网络称为集群的默认网络。此默认网络使Pods不仅可以在同一节点上而且可以在群集中的各个节点之间相互通信。 随着发展,Kubernetes 缺乏支持VNF中多个网络接口的所需功能。传统上,网络功能使用多个网络接口分离控制,管理和控制用户/数据的网络平面。他们还用于支持不同的协议,满足不同的调整和配置要求。 为了解决这个需求,英特尔实现了MULTUS的CNI插件,其中提供了将多个接口添加到Pod的功能。这允许POD通过不同的接口连接到多个网络,并且每个接口都将使用其自己的CNI插件(CNI插件可以相同或不同。这完全取决于需求和实现)。 下面是Multus CNI提供的连接到Pod的网络接口的图示。该图显示了具有三个接口的容器:eth0,net0和net1。 eth0连接kubernetes集群网络以连接kubernetes服务器/服务(例如kubernetes api-server,kubelet等)。 net0和net1是其他网络附件,并通过使用其他CNI插件(例如vlan / vxlan / ptp)连接到其他网络。 MULTUS 工作原理Kubernetes当前没有提供为POD添加额外的接口选项的规定,或支持多个CNI插件同时工作的规定,但是它确实提供了一种由api服务器扩展受支持的API的机制。使用“自定义资源定义”可以做到这一点。 MULTUS依赖于“自定义资源定义”来存储其他接口和CNI插件所需的信息。 我们首先需要确保将MULTUS二进制文件放置在/opt/cni/bin位置的所有节点上,并在/etc/cni/net.d位置创建一个新的配置文件。与MULTUS使用的kubeconfig文件一起使用。 在/etc/cni/net.d中创建的新配置文件基于集群中已经存在的默认网络配置。 在此之后,CRD用于定义新的种类名称“ NetworkAttachmentDefinition”,以及服务帐户和MULTUS的集群角色以及相应的绑定。这个新的集群角色将提供对随CRD添加的新API组以及默认API组中Pod资源的访问权限。 然后创建类型为“ NetworkAttachmentDefinition”的客户资源实例,该实例稍后将在创建具有多个接口的Pod时使用。 部署示例在本文中,我们将多次提及两件事: “默认网络”-这是您的Pod到Pod网络。这就是集群中Pod之间相互通信的方式,以及它们之间的连通性。一般而言,这被称为名为eth0的接口。此接口始终连接到您的Pod,以便它们之间可以相互连接。除此之外,我们还将添加接口。“ CRD”-自定义资源定义。自定义资源是扩展Kubernetes API的一种方式。我们在这里使用这些存储Multus可以读取的一些信息。首先,我们使用它们来存储附加到您的Pod的每个其他接口的配置。目前支持Kubernetes 1.16+版本。 安装我们建议的用于部署Multus的快速入门方法是使用Daemonset(在群集中的每个节点上运行Pod的方法)进行部署,该Pod会安装Multus二进制文件并配置Multus以供使用。 首先,克隆此GitHub存储库。 git clone https://github.com/intel/multus-cni.git && cd multus-cni我们将在此存储库中使用带有kubectl的YAML文件。 $ cat ./images/multus-daemonset.yml | kubectl apply -f -Multus daemonset 完成了那些工作?启动Multus守护程序集,这会在每个节点上运行一个pod,从而在/opt/cni/bin中的每个节点上放置一个Multus二进制文件按照字母顺序读取/etc/cni/net.d中的第一个配置文件,并为Multus创建一个新的配置文件,即/etc/cni/net.d/00-multus.conf,此配置是自动生成并基于默认网络配置(假定是按字母顺序排列的第一个配置)在每个节点上创建一个/etc/cni/net.d/multus.d目录,其中包含用于Multus访问Kubernetes API的身份验证信息。创建其他接口我们要做的第一件事是为我们附加到Pod的每个其他接口创建配置。我们将通过创建自定义资源来做到这一点。快速入门安装的一部分会创建一个“ CRD”(自定义资源定义,它是我们保留这些自定义资源的位置),我们将在其中存储每个接口的配置。 CNI 配置我们将添加的每个配置都是CNI配置。如果您不熟悉它们,让我们快速分解它们。这是一个示例CNI配置: { "cniVersion": "0.3.0", "type": "loopback", "additional": "information"}CNI配置是JSON,我们这里有一个结构,其中包含一些我们感兴趣的东西: cniVersion:告诉每个CNI插件正在使用哪个版本,如果使用的版本太晚(或太早),则可以提供插件信息。type:告诉CNI在磁盘上调用哪个二进制文件。每个CNI插件都是一个二进制文件。通常,这些二进制文件存储在每个节点上的/opt/cni/bin中,并且CNI执行此二进制文件。在这种情况下,我们指定了loopback二进制文件(它将创建一个loopback类型的网络接口)。如果这是您首次安装Multus,则可能需要验证"type"字段中的插件是否确实在/opt/cni/bin目录中。additional:此字段以此处为例,每个CNI插件都可以在JSON中指定所需的任何配置参数。这些特定于您在"type"字段中调用的二进制文件。当CNI配置更改时,您不需要重新加载或刷新Kubelets。每次创建和删除Pod时都会读取这些内容。因此,如果您更改配置,它将在下一次创建Pod时应用。如果现有Pod需要新配置,则可能需要重新启动。 将配置存储为自定义资源因此,我们要创建一个附加接口。让我们创建一个macvlan接口供Pod使用。我们将创建一个自定义资源,该资源定义接口的CNI配置。 请注意,在以下命令中有一种:NetworkAttachmentDefinition。这是我们配置的名字-它是Kubernetes的自定义扩展,定义了我们如何将网络连接到Pod。 其次,注意配置字段。您将看到这是一个CNI配置,就像我们前面解释的那样。 最后但非常重要的一点是,在元数据下注意name字段-在这里我们为该配置指定名称,这是我们告诉pod使用此配置的方式。这里的名称是macvlan-conf-我们正在为macvlan创建配置。 ...

June 5, 2020 · 2 min · jiezi

细数k8s支持的4种类型的container

截止目前k8s1.18,k8s已经支持标准容器,sidecar容器,init 容器,ephemeral 容器 4种类型的containers。本文我们详细介绍一下这4种容器的特性已经使用场景。 Ephemeral 容器临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的ContainerSpec段进行描述,但许多字段是不相容且不允许的。 临时容器没有端口配置,因此像ports,livenessProbe,readinessProbe这样的字段是不允许的。Pod 资源分配是不可变的,因此resources配置是不允许的。有关允许字段的完整列表,请参见临时容器参考文档。临时容器是使用 API 中的一种特殊的ephemeralcontainers处理器进行创建的,而不是直接添加到pod.spec段,因此无法使用kubectl edit来添加一个临时容器。 与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。 为什么我们需要Ephemeral 容器? 我们知道容器的优点是它们通过使用不变方法提供所有必需的依赖项来运行隔离的进程。通过仅将所需的依赖项添加到镜像中,容器可以降低攻击面并提供更快的启动和部署。使用“distroless”方法构建容器镜像(基于scratch),通过仅包含已编译的应用程序二进制文件,将容器镜像提升到了一个新的水平。与普通的容器镜像不同,它们不基于任何种类的Linux发行版,因此不包含任何其他可通过kubectl exec执行以进行故障排除的二进制文件和工具。这就决定了该容器有助于提供安全可靠的运行时环境,但也很难在问题发生时进行调试。 在这种情况下,临时容器发挥作用。它们实现了调试容器附加到主进程的功能,然后你可以用于调试任何类型的问题。调试容器可以基于任何镜像,因此可以根据您的需求进行定制。您可以构建自己的调试镜像,其中包含特殊的调试二进制文件或仅包含curl,OpenSSL和MongoDB客户端之类的工具。但是,您也可以选择Linux发行版(如Ubuntu)或仅运行Busybox镜像,这两个镜像都已经包含了许多有用的工具。 如何使用临时容器? 临时容器是alpha功能,因此默认情况下处于禁用状态。您将需要激活以下功能门才能使用它们: 临时容器PodShareProcessNamespace(v1.16中的beta版,因此默认情况下已启用)本节中的示例演示了临时容器如何出现在 API 中。 通常,您可以使用kubectl插件进行故障排查,从而自动化执行这些步骤。 临时容器是使用 Pod 的ephemeralcontainers子资源创建的,可以使用kubectl --raw命令进行显示。首先描述临时容器被添加为一个EphemeralContainers列表: { "apiVersion": "v1", "kind": "EphemeralContainers", "metadata": { "name": "example-pod" }, "ephemeralContainers": [{ "command": [ "sh" ], "image": "busybox", "imagePullPolicy": "IfNotPresent", "name": "debugger", "stdin": true, "tty": true, "terminationMessagePolicy": "File" }]}使用如下命令更新已运行的临时容器example-pod: kubectl replace --raw /api/v1/namespaces/default/pods/example-pod/ephemeralcontainers -f ec.json这将返回临时容器的新列表: { "kind":"EphemeralContainers", "apiVersion":"v1", "metadata":{ "name":"example-pod", "namespace":"default", "selfLink":"/api/v1/namespaces/default/pods/example-pod/ephemeralcontainers", "uid":"a14a6d9b-62f2-4119-9d8e-e2ed6bc3a47c", "resourceVersion":"15886", "creationTimestamp":"2019-08-29T06:41:42Z" }, "ephemeralContainers":[ { "name":"debugger", "image":"busybox", "command":[ "sh" ], "resources":{ }, "terminationMessagePolicy":"File", "imagePullPolicy":"IfNotPresent", "stdin":true, "tty":true } ]}可以使用以下命令查看新创建的临时容器的状态: ...

June 2, 2020 · 2 min · jiezi

k8s部署单实例VictoriaMetrics完整教程

上一篇文章,我们讲述了如何利用VictoriaMetrics作为Prometheus的长期存储,来实现大规模k8s集群的监控。本文主要讲述部署单实例VictoriaMetric到k8s集群中。 部署VictoriaMetrics本文中,我们只会部署一个单实例的VictoriaMetrics。我们会在以后的文章中部署集群版本。 完整的yaml如下: --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: victoriametrics namespace: kube-system annotations: volume.beta.kubernetes.io/aws-block-storage-additional-resource-tags: "project=victoriametrics" spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Gi--- apiVersion: apps/v1 kind: StatefulSet metadata: labels: app: victoriametrics name: victoriametrics namespace: kube-system spec: serviceName: pvictoriametrics selector: matchLabels: app: victoriametrics replicas: 1 template: metadata: labels: app: victoriametrics spec: containers: - args: - --storageDataPath=/storage - --httpListenAddr=:8428 - --retentionPeriod=1 image: victoriametrics/victoria-metrics imagePullPolicy: IfNotPresent name: victoriametrics ports: - containerPort: 8428 protocol: TCP readinessProbe: httpGet: path: /health port: 8428 initialDelaySeconds: 30 timeoutSeconds: 30 livenessProbe: httpGet: path: /health port: 8428 initialDelaySeconds: 120 timeoutSeconds: 30 resources: limits: cpu: 2000m memory: 2000Mi requests: cpu: 2000m memory: 2000Mi volumeMounts: - mountPath: /storage name: storage-volume restartPolicy: Always priorityClassName: system-cluster-critical volumes: - name: storage-volume persistentVolumeClaim: claimName: victoriametrics--- apiVersion: v1 kind: Service metadata: labels: app: victoriametrics name: victoriametrics namespace: kube-system spec: ports: - name: http port: 8428 protocol: TCP targetPort: 8428 selector: app: victoriametrics type: ClusterIPPS: ...

June 2, 2020 · 13 min · jiezi

Kubernetes集群node节点规格的选择

创建Kubernetes集群时,首先出现的问题之一是:“我应该使用哪种类型的node节点,其中有多少个? 如果要构建本地群集,应该订购一些上一代的服务器,还是使用数据中心中的十几台旧计算机? 或者,如果您使用的是诸如Google Kubernetes Engine(GKE)之类的托管Kubernetes服务,是否应该使用八个n1-standard-1或两个n1-standard-4实例来实现所需的计算能力? 集群容量通常,Kubernetes集群可以看作将一组单个节点抽象为一个大的“超级节点”。 该超级节点的总计算能力(就CPU和内存而言)是所有组成节点的能力之和。 有多种方法可以计算出集群的所需目标容量。 例如,假设您需要一个总容量为8个CPU内核和32 GB RAM的集群。 例如,由于要在集群上运行的一组应用程序需要此数量的资源。以下是设计集群的两种可能方法: 这两个选项都将导致群集具有相同的容量-但左边的选项使用4个较小的节点,而右边的选项使用2个较大的节点。 哪个更好? 为了解决这个问题,让我们看一下“很少有大节点”和“很多小节点”这两个相反方向的利弊。 请注意,本文中的“节点”始终指的是工作程序节点。主节点的数量和大小的选择是一个完全不同的主题。数量少的大资源节点在这个方向上,最极端的情况是拥有一个提供全部所需集群容量的单个工作节点。 在上面的示例中,这将是具有16个CPU内核和16 GB RAM的单个工作节点。 让我们看看这种方法可能具有的优势。 1. 较少的管理负担简而言之,与必须管理大量计算机相比,管理少量计算机较省力。 更新和补丁可以更快地应用,机器可以更轻松地保持同步。 此外,几台机器上的预期故障的绝对数量比多台机器要少。 但是,请注意,这主要适用于裸机服务器,不适用于云实例。 如果您使用云实例(作为托管Kubernetes服务的一部分或您在云基础架构上自己的Kubernetes安装的一部分),则将对基础机器的管理外包给云提供商。 因此,在云中管理10个节点并没有比在云中管理单个节点更多的工作。 2. 更少的成本虽然功能更强大的机器比低端机器更昂贵,但价格上涨并不一定是线性的。 换句话说,一台具有10个CPU内核和10 GB RAM的计算机可能比10台具有1个CPU内核和1 GB RAM的计算机便宜。 但是,请注意,如果您使用云实例,则这可能不适用。 在主要云提供商Amazon Web Services,Google Cloud Platform和Microsoft Azure的当前定价方案中,实例价格随容量线性增加。 例如,在Google Cloud Platform上,64个n1-standard-1实例的成本与单个n1-standard-64实例的成本完全相同—并且这两个选项都为您提供64个CPU内核和240 GB内存。 因此,在云中,通常无法使用大型计算机节省任何资金。 3. 允许运行占用资源多的应用拥有大型节点可能只是您要在集群中运行的应用程序类型的要求。 例如,如果您有一个需要8 GB内存的机器学习应用程序,则无法在只有1 GB内存的节点的集群上运行它。 但是您可以在具有10 GB内存节点的集群上运行它。 1. 每个节点运行太多的应用在更少的节点上运行相同的工作负载自然意味着在每个节点上运行更多的Pod。 这可能成为一个问题。 原因是每个Pod都会在节点上运行的Kubernetes代理上引入一些开销-例如容器运行时(例如Docker),kubelet和cAdvisor。 例如,kubelet对节点上的每个容器执行常规的活动性和就绪性探针-更多的容器意味着kubelet在每次迭代中需要进行更多的工作。 cAdvisor收集节点上所有容器的资源使用情况统计信息,并且kubelet定期查询此信息并将其公开在其API上-再次,这意味着cAdvisor和kubelet在每次迭代中都需要做更多的工作。 如果Pod的数量变大,这些事情可能会开始减慢系统速度,甚至使系统不可靠。、 有报告称节点未准备就绪,因为常规的kubelet运行状况检查花费了太长时间,无法遍历节点上的所有容器。 由于这些原因,Kubernetes建议每个节点最多110个Pod。 直到此数目,Kubernetes已经过测试,可以在常见节点类型上可靠地工作。 ...

June 2, 2020 · 1 min · jiezi

谈谈stop容器

docker stop对于docker来说,一般来说通过docker stop命令来实现停止容器,而不是docker kill。 具体命令如下: docker stop [OPTIONS] CONTAINER [CONTAINER...]容器内的主进程(PID为1的进程)将收到SIGTERM,并在宽限期之后收到SIGKILL。在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。 至于这个宽限期默认是10s,当然可以通过参数来制定具体时间。 docker stop --helpUsage: docker stop [OPTIONS] CONTAINER [CONTAINER...]Stop one or more running containersOptions: --help Print usage -t, --time int Seconds to wait for stop before killing it (default 10)而对于k8s来说,pod的宽限期默认是30s。通过terminationGracePeriodSeconds参数设置。 为什么需要优雅stop docker ?你的程序需要一些退出工作,比如保存checkpoint,回收一些资源对象等。如果你的服务是一个http server,那么你需要完成已经处理的请求。如果是长链接,你还需要主动关闭keepalive。 如果你是在k8s中运行容器,那么k8s整个机制是一种基于watch的并行机制,我们不能保证操作的串行执行。比如在删除一个Pod的时候,需要更改iptables规则,LB的upstream 摘除等。 你的应用程序为什么接收不到SIGTERM停机信号?你的业务进程不是1号进程Dockerfile中支持两种格式定义入口点:shell格式和exec 格式。 exec格式如下: ENTRYPOINT ["/app/bin/your-app", "arg1", "arg2"]该格式能保证你的主进程接受到停机信号。 示例: 程序代码如下: package mainimport ( "fmt" "os" "os/signal" "syscall" "time")func main() { c := make(chan os.Signal) // 监听信号 signal.Notify(c, syscall.SIGTERM) go func() { for s := range c { switch s { case syscall.SIGTERM: fmt.Println("退出:", s) ExitFunc() default: fmt.Println("其他信号:", s) } } }() fmt.Println("启动了程序") sum := 0 for { sum++ fmt.Println("休眠了:", sum, "秒") time.Sleep(1 * time.Second) }}func ExitFunc() { fmt.Println("开始退出...") fmt.Println("执行清理...") fmt.Println("结束退出...") os.Exit(0)}Dockerfiler如下,我们采用多阶段构建: ...

May 30, 2020 · 4 min · jiezi

小试-cdk8s

cdk8s是一个由aws开源的软件开发框架,用于使用熟悉的编程语言和丰富的面向对象的API定义Kubernetes应用程序和可重用的抽象。 cdk8s生成纯Kubernetes YAML--您可以使用cdk8s为在任何地方运行的任何Kubernetes集群定义应用程序。 特性与Kubernetes一起使用:您可以使用cdk8s为在任何地方运行的任何Kubernetes集群(包括任何云或本地)定义应用程序。 cdk8s在您的开发环境中本地运行,并生成可应用于任何集群的标准Kubernetes YAML。多语言支持:目前将支持TypeScript,JavaScript,Python,Java和.NET,将来还会有更多支持。它可以与Kubernetes的任何上游版本一起使用。支持核心Kubernetes对象和自定义资源:您可以从任何Kubernetes API版本和自定义资源定义导入对象以与cdk8s一起使用。这使得使用cdk8s轻松编写整个Kubernetes应用程序变得容易,并在应用程序更改时使它们保持最新。与GitOps工作流程完美配合,使您在修改配置时以及在API版本之间轻松查看更改。只需使用cdk8来合成新的YAML配置文件并将它们提交到git repo。社区驱动。设计原理cdk8s应用程序是使用一种受支持的编程语言编写的程序。它们被构造为构造树。 树的根是一个App构造。在应用程序中,用户可以定义任意数量的图表(扩展了Chart类的类)。每个图表都被合成到一个单独的Kubernetes清单文件中。图表依次由任意数量的构造组成,最终由资源组成,这些资源代表任何Kubernetes资源,例如Pod,Service,Deployment,ReplicaSet等。 构造是cdk8的基本构建块。它们是通过普通的面向对象的类来构成和创建更高级别的抽象的工具。 如果您来自Kubernetes世界,则可以将构造视为以编程方式定义的Helm Charts。关于“以编程方式定义”构造的好处是,我们可以使用它们来利用面向对象编程的全部功能。例如: 您可以使用强类型数据类型来表达抽象的API您可以表达与方法和属性的丰富交互您可以通过接口和基类创建多态编程模型通过常规软件包管理器共享它们使用我们熟悉的测试工具和技术对其进行测试版本管理cdk8s应用程序仅定义Kubernetes应用程序,实际上并未将其应用于集群。执行某个应用程序时,它会将应用程序中定义的所有图表综合到dist目录中,然后可以使用kubectl apply -f dist/chart.k8s.yaml或GitOps工具(如Flux)将这些图表应用于任何Kubernetes集群。 示例让我们来看一个简单的"Hello,World!" TypeScript中的示例。 先决条件 Node.js >= 10.x你最喜欢的 editor/IDEyarn (可选)个人比较喜欢vscode,vscode 对cdk8s支持非常好。 安装CLI cdk8s有一个CLI,其中包含一些有用的命令。让我们从全局安装cdk8s CLI开始: $ npm install -g cdk8s-cli安装成功有类似输出: usr/local/bin/cdk8s -> /usr/local/lib/node_modules/cdk8s-cli/bin/cdk8s+ cdk8s-cli@0.23.0创建工程 现在,我们将使用cdk8s init命令创建一个新的TypeScript cdk8s应用程序: $ mkdir hello$ cd hello$ cdk8s init typescript-appcreating a new project from template: typescript-app...这将执行以下操作: 创建一个新的项目目录安装cdk8s作为依赖项导入所有Kubernetes API对象将TypeScript编译为JavaScript最终我们可以看到如下输出: ======================================================================================================== Your cdk8s typescript project is ready! cat help Print this message Compile: npm run compile Compile typescript code to javascript (or "yarn watch") npm run watch Watch for changes and compile typescript in the background npm run build Compile + synth Synthesize: npm run synth Synthesize k8s manifests from charts to dist/ (ready for 'kubectl apply -f') Deploy: kubectl apply -f dist/*.k8s.yaml Upgrades: npm run import Import/update k8s apis (you should check-in this directory) npm run upgrade Upgrade cdk8s modules to latest version npm run upgrade:next Upgrade cdk8s modules to latest "@next" version (last commit)========================================================================================================watch ...

May 29, 2020 · 2 min · jiezi

您可以在Kubernetes中使用API网关公开微服务吗

在Kubernetes中,Ingress是一个组件,可将流量从群集外部路由到群集中的服务和Pod。 简而言之,Ingress充当反向代理或负载平衡器:所有外部流量都路由到Ingress,然后路由到其他组件。 尽管最受欢迎的Ingress是ingress-nginx项目,但是在选择和使用Ingress时还有其他几种选择。 您可以从以下Ingress控制器中选择: 处理诸如Contour或Treafik Ingress之类的HTTP流量支持UDP和TCP流量,例如Citrix Ingress支持Websocket,例如HAProxy Ingress还有其他混合式Ingress控制器可以与现有的云提供商集成,例如Zalando的Skipper Ingress。 当谈到Kubernetes中的API网关时,有一些流行的选择可供选择。 选项1 — API网关之王:Kong如果要构建API,则可能会对Kong Ingress提供的功能感兴趣。 Kong是建立在Nginx之上的API网关。 Kong专注于API管理,并提供身份验证,速率限制,重试,断路器等功能。 Kong的有趣之处在于它以Kubernetes Ingress的形式打包。 因此,它可以在您的群集中用作用户和后端服务之间的网关。 您可以使用标准Ingress对象将API暴露给外部流量: apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: my-ingressspec: rules: - host: example.com http: paths: - path: / backend: serviceName: api-service servicePort: 80但是 在安装过程中,Kong的控制器会注册自定义资源定义(CRD)。 这些自定义扩展之一与Kong的插件有关。 如果您希望通过IP地址限制对Ingress的请求,则可以使用以下方法创建限制的定义: apiVersion: configuration.konghq.com/v1kind: KongPluginmetadata: name: rl-by-ipconfig: hour: 100 limit_by: ip second: 10plugin: rate-limiting您可以在Ingress中使用以下注释来引用限制: apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: my-ingress annotations: plugins.konghq.com: rl-by-ipspec: rules: - host: example.com http: paths: - path: / backend: serviceName: api-service servicePort: 80您可以在官方文档中浏览有关Kong的自定义资源定义(CRD)。 ...

May 26, 2020 · 2 min · jiezi

Open-Policy-Agent简化了微服务授权

随着微服务的发展,经常遇到实施身份验证和授权(A&A)的问题。我们需要一个强大且集中管理的身份验证和授权策略。但是,应用程序的分布式性质使其难以实现。在本文中,我将探讨Open Policy Agent如何帮助简化授权问题。 让我们快速查看“身份验证和授权”的定义。认证是指识别用户(“who”)。而授权是指确定经过身份验证的用户具有的访问级别(“what”)。 我这篇文章的重点是授权部分。为了简单起见,我创建了一个带有一组微服务的示例应用程序。有一个基本的用户界面,我们可以在其中执行各种操作并查看结果。该应用程序的唯一目的是显示Open Policy Agent如何处理各种授权方案。在后续文章中,我们将扩展该应用程序的范围,以涵盖日益复杂的用例和策略管理。 示例应用首先,关于应用程序的一些上下文。我以销售团队通常使用的CPQ应用程序为客户配置报价为例。 有以下角色: 销售–具有“销售”角色的用户可以为其客户创建新报价并更新报价。但是,具有“销售”角色的用户不能删除商品。销售支持–支持人员,他们可以查看所有报价,但不能编辑任何报价。、销售管理员–行政人员可以查看所有报价,但不能编辑/创建任何报价。但是,如果需要确保清理,他们可以删除要约。由于我们专注于授权部分,因此我假设用户已经过身份验证,并且具有有效的JSON Web令牌(JWT)。每个API请求都在请求标头中包含此JWT。 在此处从github下载示例应用程序。按照自述文件中的安装说明进行操作,您应该可以使用URL http://<MINIKUBE URL>/访问UI。 授权实战基于我们在上面看到的角色,期望销售团队能够 创建新报价列出报价更新现有报价而销售支持团队只能列出报价,而不能编辑/创建报价。 Sales Admin团队只能列出报价并将其删除。 UI显示了多个按钮,每个按钮代表用户的操作。选择您要使用的角色,然后尝试创建,编辑或删除商品。 UI将提供有关操作是否成功的反馈。 那么,这里发生了什么?让我们快速了解一下当前的设置。 该应用程序具有两个微服务优惠和客户。 NGINX反向代理将这些API公开给外界。 NGINX截获每个API请求并请求授权服务以验证是否允许用户执行请求的操作。我们使用NGINX的auth_request指令来拦截传入的API调用。每个API调用都有一个Authorization标头,其中包含JWT。包括角色在内的整个用户信息都包含在JWT中。 授权服务有两个容器: 授权–一种定制服务(Authorization),用于接收请求并为Open Policy Agent创建格式化的输入请求。开放策略代理(OPA)–作为辅助工具运行,并公开http端点以与授权容器进行通信。基本上,NGINX将/authorize请求发送到Authorization容器以授权API调用。然后,授权服务咨询开放策略代理是否授权请求(是/否)。然后,它向NGINX返回成功(200 OK)或错误(403 Forbidden)响应。因此,NGINX允许API调用或向客户端返回403 Forbidden响应。 Open Policy Agent 是什么?Open Policy Agent(OPA,发音为“ oh-pa”)是一种开放源代码的通用策略引擎,它统一了整个堆栈中的策略执行。 OPA提供了一种高级的声明性语言,可让您将策略指定为代码和简单的API,以减轻软件决策的负担。您可以使用OPA在微服务,Kubernetes,CI / CD管道,API网关等中实施策略。 基本上,OPA将决策与执法脱钩。它接受结构化数据作为输入(JSON),并且可以返回决策(对/错)或任意结构化数据作为输出。 OPA使用rego作为策略语言。您可以在https://www.openpolicyagent.org/docs/latest/上了解有关rego和开放策略代理的更多信息。 授权服务详解让我们详细查看授权服务,以了解其工作原理。 我们在服务器模式下运行Open Policy Agent,并利用其REST API更新策略并获取策略决策。 Open Policy Agent公开REST API来创建或更新策略。PUT /v1/policies/<id>Content-Type: text/plain对于我们的示例,使用带有以下请求的终结点(在GitHub README中也提到了)来更新OPA中的策略。 curl -X PUT --data-binary @policies/httpapi.authz.rego http://<MINIKUBE URL>/authorize/v1/policies/httpapi/authz要根据此政策做出决定,还有另一个APIPOST /v1/data/<path>Content-Type: application/json这里的<path>是由软件package标识的策略的路径,例如package httpapi.authz。对于我们的示例,要删除商品ID“ 1000”,授权服务将使用以下请求正文调用端点http://localhost:8181/data/httpapi/authz: ...

May 26, 2020 · 1 min · jiezi