CKA 相关信息和资料总结
考试注意事项
- 考试前 15 分钟进入考试界面. 涉及确认身份可以带护照. 检查周围环境.桌面环境以及提示注意事项.全程全英文对话沟通.
- 进入考题,考题是中文显示,有些翻译不是很好,建议打开英文版查看.
- 建议找个好一点的网络考试,可以选择使用 VPN 或者公司网络.
- 如果考试中断,新建 Tab 页申请进入.
- Chrome 浏览器.
- 考试时间比较紧张.建议对于比较难的题目暂时放下,记录在提供的
note表里, 做完简单的再功课. - 对于
Kubernetes.io的内容是可以直接拷贝粘贴的. - 节省时间的技巧:
- 尽量使用
kubectl run命令 - 可以将相关的内容保存标签,方便快速打开.
- CLI 的
-h求助 - 尽量使用简写,例如
Namespace - ns等. source < (kubectl completion bash)命令补全.
- 尽量使用
Scheduling [调度] 5%
Exam1: 创建一个运行 60 次,同时运行 2 个作业的 Job
参考链接 Jobs - Run to Completion
|
|
Exam: 设置现有名为 myjob 的 Job 的副本数为 10.
|
|
注意: - parallelism : 并行执行的数量. - completions: 运行 job 成功的次数 - RestartPolicy: 仅支持 Never 或 OnFailure - activeDeadlineSeconds: 如果 Pod 失败时, 重试最大时间, 超过这个时间就不会继续重试.
Exam: Static Pod
在指定位置创建Pod清单, 然后编辑用于kubelet(/etc/systemd/system/kubelet.service) 的systemd服务文件, 包含--pod-manifest-path=/specified/path. 一旦完成, 重新启动服务.
|
|
效果如下:
|
|
Exam: 仅在指定节点上运行 Jenkins Pod
Logging / Monitoring [日志 / 监控] 5%
Exam: 找到使用 CPU 资源最多的 Pod
|
|
|
|
Exam: 找到带有字符串 Some-error message here 的错误信息
kubernetes.io/docs/concep… see kubectl logs and /var/log for system services
Application Lifecycle Management [应用程序生命周期管理] 8%
Cluster [集群] 11%
Exam: 按名字排序列出所有 PresistenteVolumes
|
|
Exam: 使用应用程序 nslookup 查找 service 和 pod 的 DNS 记录
kubernetes.io/docs/concep…
|
|
|
|
Exame: 对deployment做rollingUpdate,再滚回来
|
|
Exam: ENV
Use Pod Field
show code
root@test-9:~# kubectl get deploy -o yaml | grep env -C 10
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
demo: "true"
spec:
containers:
- env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: SECRET_USER
valueFrom:
secretKeyRef:
key: user
name: demo
root@test-9:~#
root@test-9:~# kubectl exec -ti nginx-f7d4dc847-skb74 /bin/bash
root@nginx-f7d4dc847-skb74:/# env | grep MY_NODE
MY_NODE_NAME=test-10
root@nginx-f7d4dc847-skb74:/#
Use Container Filed
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox:1.24
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
restartPolicy: Never
Exam: 对node做taint (taint a node)
注意: taint指定的 key:value 与node的label之间没有任何关系! 在添加taint的时候,需要指定: key=value:effect 在删除taint的时候,不需要指定 value,格式为: key:effect
show code
root@test-9:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-5b444f5b58-dpvzq 1/1 Running 0 2m 10.244.0.7 test-9
nginx-5b444f5b58-k6qxp 1/1 Running 0 2m 10.244.0.8 test-9
nginx-5b444f5b58-n7prf 1/1 Running 0 2m 10.244.0.9 test-9
nginx-5b444f5b58-r4265 1/1 Running 0 2m 10.244.0.11 test-9
nginx-5b444f5b58-rs2hn 1/1 Running 0 2m 10.244.0.10 test-9
nginx-5b444f5b58-v6r2x 1/1 Running 0 2m 10.244.0.6 test-9
root@test-9:~#
root@test-9:~# kubectl taint node test-9 taint=true:NoExecute
node "test-9" tainted
root@test-9:~#
root@test-9:~# kubectl describe node test-9
Name: test-9
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/hostname=test-9
node-role.kubernetes.io/master=
Annotations: flannel.alpha.coreos.com/backend-data={"VtepMAC":"9a:e5:cf:c9:fb:79"}
flannel.alpha.coreos.com/backend-type=vxlan
flannel.alpha.coreos.com/kube-subnet-manager=true
flannel.alpha.coreos.com/public-ip=10.144.96.185
node.alpha.kubernetes.io/ttl=0
volumes.kubernetes.io/controller-managed-attach-detach=true
Taints: taint=true:NoExecute
CreationTimestamp: Mon, 13 Nov 2017 20:56:37 +0800
root@test-9:~#
root@test-9:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-5b444f5b58-2s5dw 1/1 Running 0 28s 10.244.1.24 test-10
nginx-5b444f5b58-b6pds 1/1 Running 0 28s 10.244.1.23 test-10
nginx-5b444f5b58-cg75j 1/1 Running 0 28s 10.244.1.21 test-10
nginx-5b444f5b58-d8nbl 1/1 Running 0 28s 10.244.1.20 test-10
nginx-5b444f5b58-pncbm 1/1 Running 0 28s 10.244.1.18 test-10
nginx-5b444f5b58-zbc4h 1/1 Running 0 28s 10.244.1.22 test-10
root@test-9:~#
root@test-9:~# kubectl taint node test-9 taint:NoExecute-
node "test-9" untainted
root@test-9:~#
Effect支持:
NoSchedule/NoExecute/PreferNoSchedule
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
Tolerations支持:
指定匹配 key/value和effect tolerations:
key: “key” operator: “Equal” value: “value” effect: “NoSchedule” 指定 key存在且指定effect tolerations:
key: “key” operator: “Exists” effect: “NoSchedule” 只要有任何key存在 tolerations:
operator: “Exists” 指定key存在 tolerations:
key: “key” operator: “Exists” 代表往node添加taint后,多长时间之内,该pod依然可以存活(时间结束后,将被删除) tolerations:
key: “key1” operator: “Equal” value: “value1” effect: “NoExecute” tolerationSeconds: 3600 例子:
show code
root@test-9:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-5b444f5b58-2s5dw 1/1 Running 0 16m 10.244.1.24 test-10
nginx-5b444f5b58-b6pds 1/1 Running 0 16m 10.244.1.23 test-10
nginx-5b444f5b58-cg75j 1/1 Running 0 16m 10.244.1.21 test-10
nginx-5b444f5b58-d8nbl 1/1 Running 0 16m 10.244.1.20 test-10
nginx-5b444f5b58-pncbm 1/1 Running 0 16m 10.244.1.18 test-10
nginx-5b444f5b58-zbc4h 1/1 Running 0 16m 10.244.1.22 test-10
root@test-9:~#
root@test-9:~# kubectl taint node test-9 taint=true:NoExecute
node "test-9" tainted
root@test-9:~#
root@test-9:~# kubectl edit deploy nginx
deployment "nginx" edited
root@test-9:~#
root@test-9:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-9bf4c9c69-27r6m 1/1 Running 0 17s 10.244.1.26 test-10
nginx-9bf4c9c69-cnjk2 1/1 Running 0 23s 10.244.0.12 test-9
nginx-9bf4c9c69-fttrd 1/1 Running 0 23s 10.244.1.25 test-10
nginx-9bf4c9c69-jw7w2 1/1 Running 0 11s 10.244.1.27 test-10
nginx-9bf4c9c69-s57h2 1/1 Running 0 12s 10.244.0.14 test-9
nginx-9bf4c9c69-z8jrn 1/1 Running 0 18s 10.244.0.13 test-9
root@test-9:~#
root@test-9:~# kubectl get deploy nginx -o yaml | grep tolerations -C 5
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- operator: Exists
status:
availableReplicas: 6
conditions:
- lastTransitionTime: 2017-11-13T13:23:03Z
root@test-9:~#
Secret
generic
root@test-9:~# kubectl create secret generic demo --from-literal=user=chenleji --from-literal=passwd=123
secret "demo" created
root@test-9:~#
root@test-9:~# kubectl get secret
NAME TYPE DATA AGE
default-token-wgrhs kubernetes.io/service-account-token 3 1h
demo Opaque 2 4s
root@test-9:~#
root@test-9:~# kubectl get secret demo -o yaml
apiVersion: v1
data:
passwd: MTIz
user: Y2hlbmxlamk=
kind: Secret
metadata:
creationTimestamp: 2017-11-13T14:12:00Z
name: demo
namespace: default
resourceVersion: "7108"
selfLink: /api/v1/namespaces/default/secrets/demo
uid: 9da9b9f4-c87c-11e7-9401-525400545760
type: Opaque
root@test-9:~#
root@test-9:~# echo -n MTIz | base64 --decode
123
root@test-9:~# echo -n Y2hlbmxlamk= | base64 --decode
chenleji
root@test-9:~#
root@test-9:~#
Storage [存储] 7%
Exam: 您有一个带有挂载卷的容器. 添加一个在卷中创建空文件的 InitContainer.
Exam: Redis 数据存储的问题
在预生产环境中运行 redis 键值对存储时, 许多部署都来自于 CI, 并在 Redis 中留下了大量陈旧的缓存数据, 这将导致测试失败. CI 管理员要求, 在每次的 staging 中部署 Redis 键值对存储时, 它都不应该被持久化其数据. 创建一个名为 non-persistent-redis 的
pod, 它指定一个名为 app-cache 的卷, 以及挂载路径 /data/redis. 它应该在 staging 命名空间中启动,并且卷不能是持久性的. 创建一个带有 EmptyDir 的 Pod, 并在 YAML 文件中添加命名空间 CI.
Exam: TLS
show code
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key
Registry
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER
--docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
volume mount
未指定挂载的具体文件名:
root@test-9:~# kubectl get deploy -o yaml | grep volume -C 5
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /secret
name: secret
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- operator: Exists
volumes:
- name: secret
secret:
defaultMode: 420
secretName: demo
status:
root@test-9:~#
root@test-9:~# kubectl exec -ti nginx-557769d5c5-45sdq /bin/bash
root@nginx-557769d5c5-45sdq:/# ls -l /secret/
total 0
lrwxrwxrwx 1 root root 13 Nov 13 14:23 passwd -> ..data/passwd
lrwxrwxrwx 1 root root 11 Nov 13 14:23 user -> ..data/user
root@nginx-557769d5c5-45sdq:/#
root@nginx-557769d5c5-45sdq:/# cat /secret/passwd
123
root@nginx-557769d5c5-45sdq:/#
指定挂载文件名:
root@test-9:~# kubectl describe secret demo
Name: demo
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
passwd: 3 bytes
user: 8 bytes
root@test-9:~#
root@test-9:~# kubectl get deploy nginx -o yaml | grep volume -C 8
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /secret
name: secret
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
tolerations:
- operator: Exists
volumes:
- name: secret
secret:
defaultMode: 420
items:
- key: user
path: haha/xx
secretName: demo
status:
root@test-9:~#
root@nginx-657c6dcd4c-56p5h:/# cat /secret/haha/xx
chenleji
root@nginx-657c6dcd4c-56p5h:/#
env
root@test-9:~# kubectl get deploy nginx -o yaml | grep env -C 6
metadata:
creationTimestamp: null
labels:
demo: "true"
spec:
containers:
- env:
- name: SECRET_USER
valueFrom:
secretKeyRef:
key: user
name: demo
image: nginx
root@test-9:~#
root@test-9:~# kubectl exec -ti nginx-548c9c4846-dgnbk /bin/bash
root@nginx-548c9c4846-dgnbk:/# env | grep SECRET
SECRET_USER=chenleji
root@nginx-548c9c4846-dgnbk:/#
Networking [网络] 11%
Exam: 创建一个网络策略,只允许通过busybox pod连接到端口8080
show code
# kubectl annotate ns default "net.beta.kubernetes.io/network-policy={\"ingress\": {\"isolation\": \"DefaultDeny\"}}"
namespace "default" annotated
# kubectl describe ns default
Name: default
Labels: <none>
Annotations: net.beta.kubernetes.io/network-policy={"ingress": {"isolation": "DefaultDeny"}}
Status: Active
No resource quota.
No resource limits.
#
# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx2-2627548522-6f5kf 1/1 Running 0 22m pod-template-hash=2627548522,run=nginx
nginx2-2627548522-8w87b 1/1 Running 0 22m pod-template-hash=2627548522,run=nginx
# kubectl get svc nginx --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
nginx NodePort 10.43.120.19 <none> 80:30014/TCP 16m run=nginx
# cat network-policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-nginx
spec:
podSelector:
matchLabels:
run: nginx
ingress:
- from:
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
access: "true"
ports:
- protocol: TCP
port: 80
# kubectl get netpol
NAME POD-SELECTOR AGE
access-nginx run=nginx 2m
# kubectl get netpol access-nginx -o yaml
apiVersion: extensions/v1beta1
kind: NetworkPolicy
metadata:
creationTimestamp: 2017-11-12T07:40:38Z
generation: 1
name: access-nginx
namespace: default
resourceVersion: "20699"
selfLink: /apis/extensions/v1beta1/namespaces/default/networkpolicies/access-nginx
uid: c72191d1-c77c-11e7-8dee-02cdc7a8bd69
spec:
ingress:
- from:
- podSelector:
matchLabels:
access: "true"
ports:
- port: 80
protocol: TCP
podSelector:
matchLabels:
run: nginx
#
# kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget nginx
Connecting to nginx (10.43.120.19:80)
index.html 100% |********************************************************************************************| 612 0:00:00 ETA
/ #
Exam : 创建一个 Ingress 资源, Ingress 控制器以及一个 Service 解析 cs.rocks.ch 的服务.
show code
First, create controller and default backend
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress/master/controllers/nginx/examples/default-backend.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress/master/examples/deployment/nginx/nginx-ingress-controller.yaml
Second, create service and expose
kubectl run ingress-pod --image=nginx --port 80
kubectl expose deployment ingress-pod --port=80 --target-port=80 --type=NodePort
Create the ingress
cat <<EOF >ingress-cka.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
spec:
rules:
- host: "cs.rocks.ch"
http:
paths:
- backend:
serviceName: ingress-pod
servicePort: 80
EOF
To test, run a curl pod
kubectl run -i --tty client --image=tutum/curl
curl -I -L --resolve cs.rocks.ch:80:10.240.0.5 http://cs.rocks.ch/
我认为,要访问ingress,在flannel网络中,应该还可以使用hostPort来暴露出ingress-nginx的80和443端口。
Mandatory commands
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml | kubectl apply -f -
Install with RBAC roles
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml | kubectl apply -f -
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/with-rbac.yaml | kubectl apply -f -
Verify installation:
kubectl get pods --all-namespaces -l app=ingress-nginx --watch