CKA考试知识总结-2

之所以要将这篇很长很长的博文拆分开,是因为站内查询因这篇长文而失效了,另外打开一个页面实在有些卡顿(⊙﹏⊙)b

Come on baby! 操起键盘就是干,继续~

复习资料

initContainer

Q: You have a Container with a volume mount. Add a init container that creates an empty file in the volume. (only trick is to mount the volume to init-container as well)
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
volumeMounts:
- mountPath: /cache
name: cache-volume
initContainers:
- name: init-touch-file
image: busybox
volumeMounts:
- mountPath: /data
name: cache-volume
command: ['sh', '-c', 'echo "" > /data/harshal.txt']
volumes:
- name: cache-volume
emptyDir: {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
root@test-9:~/henry# cat init-container.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-baidu
image: busybox
command: ['sh', '-c', 'until nslookup www.baidu.com; do echo waiting for baidu.com; sleep 2; done;']
- name: init-google
image: busybox
command: ['sh', '-c', 'until nslookup www.google.com; do echo waiting for google.com; sleep 2; done;']

root@test-9:~/henry#
root@test-9:~/henry# kubectl get pod -a
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 1m
nginx2-2627548522-6f5kf 1/1 Running 0 2h
nginx2-2627548522-8w87b 1/1 Running 0 2h
root@test-9:~/henry#
root@test-9:~/henry# kubectl describe pod myapp-pod
Name: myapp-pod
Namespace: default
Node: test-9/10.144.96.185
Start Time: Sun, 12 Nov 2017 17:43:49 +0800
Labels: app=myapp
Annotations: pod.alpha.kubernetes.io/init-container-statuses=[{"name":"init-baidu","state":{"terminated":{"exitCode":0,"reason":"Completed","startedAt":"2017-11-12T09:43:54Z","finishedAt":"2017-11-12T09:43:54Z","c...
pod.alpha.kubernetes.io/init-containers=[{"name":"init-baidu","image":"busybox","command":["sh","-c","until nslookup www.baidu.com; do echo waiting for baidu.com; sleep 2; done;"],"resources":{},"volu...
pod.beta.kubernetes.io/init-container-statuses=[{"name":"init-baidu","state":{"terminated":{"exitCode":0,"reason":"Completed","startedAt":"2017-11-12T09:43:54Z","finishedAt":"2017-11-12T09:43:54Z","co...
pod.beta.kubernetes.io/init-containers=[{"name":"init-baidu","image":"busybox","command":["sh","-c","until nslookup www.baidu.com; do echo waiting for baidu.com; sleep 2; done;"],"resources":{},"volum...
Status: Running
IP: 10.42.107.11
Init Containers:
init-baidu:
Container ID: docker://9497c4dc7c111870022e5dd873daba13f00797308b505f6e82fd1f1545744062
Image: busybox
Image ID: docker-pullable://busybox@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0
Port: <none>
Command:
sh
-c
until nslookup www.baidu.com; do echo waiting for baidu.com; sleep 2; done;
State: Terminated
Reason: Completed
Exit Code: 0
Started: Sun, 12 Nov 2017 17:43:54 +0800
Finished: Sun, 12 Nov 2017 17:43:54 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5qfpj (ro)
init-google:
Container ID: docker://5ff45db07f52c51e40b0bb77ad650aa4fbd29aa7112a4197de33ed880a04376d
Image: busybox
Image ID: docker-pullable://busybox@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0
Port: <none>
Command:
sh
-c
until nslookup www.google.com; do echo waiting for google.com; sleep 2; done;
State: Terminated
Reason: Completed
Exit Code: 0
Started: Sun, 12 Nov 2017 17:43:59 +0800
Finished: Sun, 12 Nov 2017 17:43:59 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5qfpj (ro)
Containers:
myapp-container:
Container ID: docker://88cf1ddb39e7b468d9d06c37a7d3ff1ca0d39ae9b0f46d0cf2f1788cb1482118
Image: busybox
Image ID: docker-pullable://busybox@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0
Port: <none>
Command:
sh
-c
echo The app is running! && sleep 3600
State: Running
Started: Sun, 12 Nov 2017 17:44:04 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5qfpj (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-5qfpj:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-5qfpj
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.alpha.kubernetes.io/notReady:NoExecute for 300s
node.alpha.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 1m default-scheduler Successfully assigned myapp-pod to test-9
Normal SuccessfulMountVolume 1m kubelet, test-9 MountVolume.SetUp succeeded for volume "default-token-5qfpj"
Normal Pulling 1m kubelet, test-9 pulling image "busybox"
Normal Pulled 1m kubelet, test-9 Successfully pulled image "busybox"
Normal Created 1m kubelet, test-9 Created container
Normal Started 1m kubelet, test-9 Started container
Normal Pulling 1m kubelet, test-9 pulling image "busybox"
Normal Pulled 1m kubelet, test-9 Successfully pulled image "busybox"
Normal Created 1m kubelet, test-9 Created container
Normal Started 1m kubelet, test-9 Started container
Normal Pulling 1m kubelet, test-9 pulling image "busybox"
Normal Pulled 1m kubelet, test-9 Successfully pulled image "busybox"
Normal Created 1m kubelet, test-9 Created container
Normal Started 1m kubelet, test-9 Started container
root@test-9:~/henry#

Volume

Q: When running a redis key-value store in your pre-production environments many deployments are incoming from CI and leaving behind a lot of stale cache data in redis which is causing test failures. The CI admin has requested that each time a redis key-value-store is deployed in staging that it not persist its data.
Create a pod named non-persistent-redis that specifies a named-volume with name app-cache, and mount path /data/redis. It should launch in the staging namespace and the volume MUST NOT be persistent.
Create a Pod with EmptyDir and in the YAML file add namespace: CI

Yaml格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: gcr.io/google_containers/busybox:latest
name: test-container
command: ["/bin/sh", "-c", "sleep 9999"]
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}

挂载文件到pod中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
io.wise2c.service: xx
io.wise2c.stack: stack001
name: stack001-xx
spec:
replicas: 1
template:
metadata:
labels:
io.wise2c.service: xx
io.wise2c.stack: stack001
spec:
containers:
image: nginx
name: xx
resources:
limits:
cpu: 200m
memory: 1073741824
volumeMounts:
- mountPath: /etc/resolv.conf
name: xx
subPath: resolv.conf
volumes:
- configMap:
name: stack001-xx
name: xx
- apiVersion: v1
data:
resolv.conf: "\nnameserver 10.96.0.10 \n\nsearch stack001.ns-team-2-env-44.svc.cluster.local\
\ ns-team-2-env-44.svc.cluster.local svc.cluster.local cluster.local\noptions\
\ ndots:6"
kind: ConfigMap
metadata:
labels:
io.wise2c.stack: stack001
name: stack001-xx
kind: List

挂载同一个文件到不同pod中,指定不同的名字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: busybox
command: ["/bin/sh", "-c", "sleep 999"]
volumeMounts:
- mountPath: /haha/mysql
name: site-data
subPath: mysql
- name: php
image: busybox
command: ["/bin/sh", "-c", "sleep 999"]
volumeMounts:
- mountPath: /haha/html
name: site-data
subPath: html
volumes:
- name: site-data
hostPath:
path: /data

两种类型的持久卷

PV, 使用静态的PV来挂载,需要用户自己创建PV.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
nfs:
path: /tmp
server: 172.17.0.2

PVC, 用户不用关心PV,只需要说需要什么类型的存储,即创建PVC,然后PVC自动从Storage Class中创建对应的PV。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
storageClassName: gold
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}

Storage Class:

1
2
3
4
5
6
7
8
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
type: fast
availability: nova

Pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: dockerfile/nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim

Log

Q: Find the error message with the string “Some-error message here”.
https://kubernetes.io/docs/concepts/cluster-administration/logging/
see kubectl logs and /var/log for system services

1
2
[root@dev-7 henry]# kcc logs -f --tail=10  orchestration-2080965958-khwfx -c orchestration
[root@dev-7 henry]# kcc logs -f --since=1h orchestration-2080965958-khwfx -c orchestration

kubelet日志位于/var/log/kubelet下

static pod

Q: Run a Jenkins Pod on a specified node only.
https://kubernetes.io/docs/tasks/administer-cluster/static-pod/
Create the Pod manifest at the specified location and then edit the systemd service file for kubelet(/etc/systemd/system/kubelet.service) to include --pod-manifest-path=/specified/path. Once done restart the service.

  1. Choose a node where we want to run the static pod. In this example, it’s my-node1.

    1
    [joe@host ~] $ ssh my-node1
  2. Choose a directory, say /etc/kubelet.d and place a web server pod definition there, e.g. /etc/kubelet.d/static-pod.yaml:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@my-node1 ~] $ mkdir /etc/kubernetes.d/ 
    [root@my-node1 ~] $ cat <<EOF >/etc/kubernetes.d/static-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: static-pod
    spec:
    containers:
    - image: busybox
    name: test-container
    command: ["/bin/sh", "-c", "sleep 9999"]
    EOF
  3. Configure your kubelet daemon on the node to use this directory by running it with --pod-manifest-path=/etc/kubelet.d/ argument. On Fedora edit /etc/kubernetes/kubelet to include this line:

    1
    KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
  4. Instructions for other distributions or Kubernetes installations may vary. Restart kubelet. On Fedora, this is:

    1
    [root@my-node1 ~] $ systemctl restart kubelet

效果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@dev-9 manifests]# kubectl get pod
NAME READY STATUS RESTARTS AGE
static-pod-dev-9 1/1 Running 0 34s
[root@dev-9 manifests]#
[root@dev-9 manifests]# kubectl describe pod static-pod-dev-9
Name: static-pod-dev-9
Namespace: default
Node: dev-9/192.168.1.190
Start Time: Sun, 12 Nov 2017 21:21:48 +0800
Labels: <none>
Annotations: kubernetes.io/config.hash=1dcad4affd910f45b5c3a8dbdeec8933
kubernetes.io/config.mirror=1dcad4affd910f45b5c3a8dbdeec8933
kubernetes.io/config.seen=2017-11-12T21:21:48.15196949+08:00
kubernetes.io/config.source=file
Status: Running
IP: 10.244.3.45
Containers:
test-container:
Container ID: docker://ef3e28e45e280e4a50942fc472fd025cb84a7014a64dbc57308cddbfeb1bd979
Image: busybox
Image ID: docker-pullable://busybox@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0
Port: <none>
Command:
/bin/sh
-c
sleep 9999
State: Running
Started: Sun, 12 Nov 2017 21:21:52 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts: <none>
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes: <none>
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: :NoExecute
Events: <none>
[root@dev-9 manifests]#

DNS

Q: Use the utility nslookup to look up the DNS records of the service and pod.
From this guide, https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/
Look for “Quick Diagnosis”

Services

1
$ kubectl exec -ti busybox -- nslookup mysvc.myns.svc.cluster.local

Naming conventions for services and pods:

  1. For a regular service, this resolves to the port number and the CNAME: (解析到Cluster-IP)
    my-svc.my-namespace.svc.cluster.local.
1
2
3
4
5
6
7
root@test-9:~/henry# kubectl exec -ti busybox-2520568787-kkmrw -- nslookup nginx.default.svc.cluster.local
Server: 10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name: nginx.default
Address 1: 10.43.120.19 nginx.default.svc.cluster.local
root@test-9:~/henry#
  1. For a headless service, this resolves to multiple answers(RR解析到多个Pod IP), one for each pod that is backing the service, and contains the port number and a CNAME of the pod of the form
    auto-generated-name.my-svc.my-namespace.svc.cluster.local

Pods

When enabled, pods are assigned a DNS A record in the form of

pod-ip-address.my-namespace.pod.cluster.local

For example, a pod with IP 1.2.3.4 in the namespace default with a DNS name of cluster.local would have an entry: 1-2-3-4.default.pod.cluster.local

1
2
3
4
5
6
7
root@test-9:~/henry# kubectl exec -ti busybox-2520568787-kkmrw -- nslookup 10-42-236-215.default.pod.cluster.local
Server: 10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name: 10-42-236-215.default.pod.cluster.local
Address 1: 10.42.236.215
root@test-9:~/henry#

Ingress

Q 17: Create an Ingress resource, Ingress controller and a Service that resolves to cs.rocks.ch.

  1. First, create controller and default backend
    1
    2
    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
  1. Second, create service and expose

    1
    2
    kubectl run ingress-pod --image=nginx --port 80
    kubectl expose deployment ingress-pod --port=80 --target-port=80 --type=NodePort
  2. Create the ingress

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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
  3. To test, run a curl pod

    1
    2
    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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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

    1
    2
    3
    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:

    1
    kubectl get pods --all-namespaces -l app=ingress-nginx --watch

接下来还有,请抽根烟继续!

0%