这几年来随着云原生的不断进化发展,CNCF旗下产品得到了众多行业不同规模企业的一致认可,其中明星产品之一的Kubernetes作为容器编排控制系统更是得到了广泛的应用和完善。其用pod对发布和网络的管理无论对企业还是开发者都是部署应用的一门利器,近几年热度不断攀升,而拥有CNCF旗下官方认证的从业人员也成为了市场上的香饽饽,下面就来介绍一下我刚刚考取CKAD证书的一些心得。
CNCF K8S认证
首先CNCF官方的K8S认证一共有三门,面向日常开发者的CKAD(Certified Kubernetes Application Developer),和面向容器管理者的CKA(Certified Kubernetes Administrator)和安全专精的CKS(Certified Kubernetes Security Specialist)—— 这三门课程与AWS/GCP等公有云服务商的认证不同,它们全部是上机实战,没有选择题,官方定义为性能测试,CKAD2小时考下来并不为虚。
CKAD
面向开发者的CKAD考察内容和占比如下,虽然CNCF的认证有中文可选,但我参加的考试是英文。这门认证的难度为中级,要求应试者具备基本的docker和k8s使用常识,以及linux和vim文本编辑的基本操作。这门上机考试题目16-20不等,每道题会给出一个得分比重4-8%不等,可以跳跃答题,只能在线上通过PSI的指定浏览器登录远程桌面答题,一共2小时。
- Application Design and Build 20%
- Application Deployment 20%
- Application Observability and Maintenance 15%
- Application Environment, Configuration and Security 25%
- Services and Networking 20%
费用
CKAD的官方价格不知道什么时候从300美元涨到了380,常年都会有15%的折扣码,折后约为$335(也就是我入手的价格),每年这个时候黑五折扣最大,CKAD只需$198,CKA和CKS的套装仅需$277 —— 现在还在打折。
备考
英文世界备考的最简单途径是Udemy上好评最多的培训大师Mumshad Mannambeth的线上视频课,经常打折后20多美元。新加坡居民可以通过图书馆NLB登陆获得Udemy商务版的免费使用权限,即可免费获得全部的K8S课程。 他的这门课程最大的好处是附赠全套的上机模拟,几乎覆盖所有的知识点和考点,如果你没有系统的操作过K8S,这些上机练习对于了解和实践k8s是非常有帮助的。 我同时对比过ACloudGuru上的CKAD课程,Udemy上Mumshad的课程编排、上机环境、举例讲解都更优秀,所以他干脆自立门户成立了KodeKloud线上培训,上机环境就是由此提供,就免除了我们自建k8s或者付费EKS/GKE来练习的麻烦。此课程对docker,linux,yaml需要了解的基本知识也进行了粗概介绍,对于新手也比较友好。
对于每个知识点,你需要理解它存在的意义,yaml怎样编写,以及如何用kubectl实现。上机考试时,内置浏览器可访问k8s官网,考题甚至提供了该题相关的参数文档快捷链接,比如sidecar容器的使用,课程会先介绍使用的场景,虽然机考没有选择题问,但理解业务需要即我们为什么要做,是万事的开头,其次就是通过实例熟悉一个pod内多容器的yaml编排,最后用命令来部署并查看状态。
这套课程视频时间总长约15小时,每个知识点上机lab十分钟左右,加上最后附加的几道模拟考试题1-2小时,如果投入每天1-2小时的话可在2-3周内完成。之后就可以激活报名考试赠送的两次模拟考试来测试自己的熟练度,killer.sh提供的模考环境跟真实环境非常接近,左边一览考试题目,右边远程桌面内开浏览器和terminal做题。附赠的两次模考内容相同共20题,每次激活可用36小时,答完题还可以在里面核对答案,修改练习,题目比真实题目较简单。 我是真实考试N-3天激活了第一次模考,2小时内没答完题,仔细对照答案后,N-1即考试前一天又做了一遍即通过。
考试当天
考试当天,早到了一会用Mac下载psi的机考专用客户端,打开系统环境监测要求关闭Mac运行的其他应用甚至AirPlay,折腾了几分钟登陆进去签到,等了十分钟监考官才进场,按照惯例用摄像头检查我的考试房间和桌椅,最后竟然不允许我放置带颜色的饮料在座位,几经反复用透明容器装白开水才可以继续,也是服了。我的考试共16道题,考察的内容基本都是课程的知识点内,提前20分钟做完了所有题目又回去修改检查了下之前马克的问题。 很多考试tips都告诉大家:
- 每道题的平均时间大概为6分钟,超时就跳过答后面的
- 有剩余时间先看分值高的题目
- Docker命令不熟可以–help,或者用podman
- 外接显示器不可用
- 熟练使用alias快捷输入和键盘复制粘贴而不是鼠标右键
结合系统化学习和考试实际内容,我总结出重点知识点考点脑图一份,有需要的小伙伴可以在Linkedin上加我要链接~
最后祝想报名考试的同学们好运~
友情赠送我觉得比较有用的命令:
alias
alias k='kubectl'
export do="--dry-run=client -o yaml"
alias kdr='kubectl -o yaml --dry-run=client'
alias kdp='kubectl describe pod'
alias kgp='kubectl get pod'
alias kd='kubectl describe'
Namespace
kubectl create namespace xxx
Pod
k get pods --selector env=dev --no-headers | wc -l #count pod number
kgp --selector env=prod,bu=finance,tier=frontend
k get po --show-labels
k get po -l 'env in (dev,prod)' --show-labels
k delete po -l app=green
k get po pod-with-defaults -o yaml | grep -A2 " securityContext:"
k -n neptune get pod,job | grep neb-new-job
k label pod/nginx-dev3 env=uat --overwrite #change label
k label pod nginx-dev{1..3} env- #remove label env for pod1&2&3
k label pod nginx-prod{1..2} app=nginx
k annotate pod -l app=green name=webapp
k annotate pod pod1 --list
k describe po nginx-dev{1..3} | grep -i annotations
k describe po pod1 | grep -i status:
Node
k taint nodes node01 app=green:NoSchedule
k taint nodes controlplane node-role.kubernetes.io/control-plane:NoSchedule-
k describe node node01
k label node controlplane app_type=beta
Roles
k describe pod kube-apiserver-controlplane -n kube-system
k describe rolebinding kube-proxy -n kube-system
k create role developer --namespace=default --verb=list,create,delete --resource=pods
k create rolebinding dev-user-binding --namespace=default --role=developer --user=dev-user
k get clusterroles --no-headers -o json | jq '.items | length'
k create clusterrole node-admin --verb=get,watch,list,create --resource=node
k create clusterrolebinding michelle-binding --clusterrole=node-admin --user=michelle
k auth can-i list nodes --as michelle
Run
k run redis --image=redis123 --dry-run=client -o yaml > redis-definition.yaml
k run redis -l tier=db --image=redis:alpine
k run custom-nginx --image=nginx --port=8080 --restart=never
k run httpd --image=httpd:alpine --port=80 --expose #create pod and svc
k run busybox --image=nginx --restart=Never -it -- echo "How are you"
k run busybox --image=busybox --restart=Never --dry-run -o yaml -- bin/sh -c "sleep 3600; ls" > multi-container.yaml
k replace --force -f /file.yaml
Service
k get svc -l app=my-nginx
k expose po redis --port=6379 --name redis-service #default type ClusterIP
k expose po nginx --port=80 --type=NodePort # then edit svc to add nodePort: 30080
k expose po deploy hello --port=9999 --target-port=80 # service port 9999, container port 80
k get ep -n pluto
k run tmp --restart=Never --rm -i --image=nginx:alpine -- curl project-plt-6cc-svc.pluto:3333 #service.namespace:port
k run tmp --restart=Never --rm -i --image=nginx:alpine -- curl node.ip
k run busybox --image=busybox --restart=Never -it --rm -- wget -O- <Cluster IP>:80 # temp pod verify the service
k -n xxx exec podname -- wget -O- apisvc:2222
k expose -n ingress-space deployment ingress-controller --type=NodePort --port=80 --name=ingress --dry-run=client -o yaml > ingress.yaml
k create ingress ingress --rule="ckad-mock-exam-solution.com/video*=my-video-service:8080" --dry-run=client -oyaml > ingress.yaml
#! service selector should match deploy selector
Deployment
k create deploy --image=nginx nginx
k apply -f deploy.yaml --record=true
k create deployment webapp --image=kodekloud/webapp-color --replicas=3
k get deploy --show-labels
k scale deploy webapp --replicas=20
k autoscale deploy webapp --min=10 --max=20 --cpu-percent=85
k get hpa
k rollout status deploy webapp
k set image deploy/webapp nginx=nginx:1.17.4
k rollout undo deploy webapp
k rollout history deploy webapp --revision=7
k rollout pause/resume deploy webapp
ReplicaSet
k scale rs/deploy new-replica-set --replicas=5
k edit rs xxx
k get rs -o wide | grep xxx # show history replicaset and image version
Logs
k exec -it ubuntu-sleeper -- cat /proc/1/status | grep 'Cap'
k exec pod1 -it -- sh
k logs busybox -p #prev pod log
k logs busybox > busybox-log.txt
k logs busybox --follow # -f stream log
k top pod busybox --containers > file.log
kubectl top pod --all-namespaces | sort --reverse --key 3 --numeric | head -3 > cpu-usage.txt
k get events --sort-by=.metadata.creationTimestamp
Observability
kubectl describe pod nginx | grep -i readiness
k explain Pod.spec.containers.livenessProbe
Job
k create job nodeversion --image=node -- node -v # job print node version
k create cronjob date-job --image=busybox --schedule="*/1 * * * *" -- bin/sh -c "date; echo Hello from kubernetes cluster" #every min
Configmap
k create cm myconfigmap --from-literal=appname=myapp
k -n moon create cm configmap-web-moon-html --from-file=index.html=/opt/course/15/web-moon.html
echo -e "foo3=lili\nfoo4=lele" > config.txt
k exec nginx -- env #verify env
Secret
k create secret name1 --from-literal=user=aaa --from-literal=pass=bbb
k -n neptune get secrets -oyaml | grep annotations -A 1 # shows secrets with first annotation
k describe secret aaa # show base64 token
echo axo978 | base64 -d
k -n moon exec secret-handler -- find /tmp/secret2
k -n moon exec secret-handler -- cat /tmp/secret2/key
MISC
k exec -it kube-apiserver-controlplane -n kube-system -- kube-apiserver -h | grep 'enable-admission-plugins'
grep enable-admission-plugins /etc/kubernetes/manifests/kube-apiserver.yaml
vi /etc/kubernetes/manifests/kube-apiserver.yaml
add - --enable-admission-plugins=NodeRestriction,NamespaceLifecycle
ps -ef | grep kube-apiserver | grep admission-plugins
PV, PVC -- default namespace can claim PV in other namespace, delete PVC
kubectl patch pv k8s-pv-kafka02 -p '{"metadata":{"finalizers":null}}'
Helm
helm -n xxxx ls -a
helm show values bitnami/appache | yq e | grep repli # parse yaml with color
helm -n mercury install internal-issue-report-apache bitnami/apache --set replicaCount=2
Webhook
kubectl -n webhook-demo create secret tls webhook-server-tls \
--cert "/root/keys/webhook-server-tls.crt" \
--key "/root/keys/webhook-server-tls.key"
Podman
podman run -d --name sun-cipher registry.killer.sh:5000/sun-cipher:v1-podman
参考资源:
官方:
民间: