KEMBAR78
k8s practice 2023.pptx
Kubernetes Practice
Dept. of smart finance
Korea Polytechnics
Requirements
• We’ll make 2 VMs, one is master node and the other is worker node.
Each node need to be set as below
• CPU : 2 core (minimum)
• RAM : 3GB (minimum)
• Storage: 30GB(minimum)
• OS : Ubuntu 22.04 (preferred)
Network setup
• 1. Set a host network manager (menu -> file -> host network manager…)
In virtual box
Network setup
• Adaptor 1 : NAT
• Adaptor 2: Host-Only Network
In virtual box
setup network info while installing
Network setup
• check
vi /etc/netplan/00-installer-config.yaml
NAT
Host-Only Adapter
Master
Reference : https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#network-plugin-requirem
netplan apply
Network setup
• vi /etc/sysctl.d/k8s.conf
• sysctl --system
Network setup
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
hostname
vi /etc/cloud/cloud.cfg
systemctl restart systemd-logind.service
hosts
• vi /etc/hosts
192.168.56.60 master
192.168.56.61 worker01
hostname setting
• Hostname setting in worker node
• If worker’s hostname is equal to master, then you will see following error message on
worker node when executing kubeadm join
>> a Node with name ** and and status "Ready" already exists in the cluster.
hostnamectl set-hostname worker01
vi /etc/cloud/cloud.cfg
Requirements
• Memory swap off
swapoff -a
•
• Check ports
Docker
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
vi /etc/fstab
VM 복제
worker node
• check
vi /etc/netplan/00-installer-config.yaml
• hostnamectl set-hostname worker01
netplan apply
[tip] virtual box range port forwarding
1. Vbox register(If needed) : VBoxManage registervm /Users/sf29/VirtualBox VMs/Worker/Worker.vbox
2. for i in {30000..30767}; do VBoxManage modifyvm "Worker" --natpf1 "tcp-port$i,tcp,,$i,,$i"; done
https://kubernetes.io/docs/reference/networking/ports-and-protocols/
ufw allow "OpenSSH"
ufw enable
ufw allow 6443/tcp
ufw allow 2379:2380/tcp
ufw allow 10250/tcp
ufw allow 10259/tcp
ufw allow 10257/tcp
ufw status
master(control plane) node
Worker node
ufw allow "OpenSSH"
ufw enable
ufw status
ufw allow 10250/tcp
ufw allow 30000:32767/tcp
ufw status
Port Open
Kubernetes 설치
Kubernetes setup
Install containerd
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu 
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install containerd.io
systemctl stop containerd
mv /etc/containerd/config.toml /etc/containerd/config.toml.orig
containerd config default > /etc/containerd/config.toml
vi /etc/containerd/config.toml
SystemdCgroup = true
systemctl start containerd
systemctl is-enabled containerd
systemctl status containerd
Kubernetes setup
Install kubernetes
apt install apt-transport-https ca-certificates curl -y
# curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
#echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
apt update
apt install kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl # 패키지가 자동으로 업그레이드 되지 않도록 고정
kubeadm version
kubelet --version
kubectl version
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
CNI(컨테이너 네트워크 인터페이스) 플러그인 설치
mkdir -p /opt/bin/
curl -fsSLo /opt/bin/flanneld https://github.com/flannel-io/flannel/releases/download/v0.19.0/flanneld-amd64
chmod +x /opt/bin/flanneld
lsmod | grep br_netfilter
kubeadm config images pull
Master node setting
Kubeadm init
Your ip address
Reference : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kube
kubeadm init --pod-network-cidr=10.244.0.0/16 
--apiserver-advertise-address=192.168.56.60 
--cri-socket=unix:///run/containerd/containerd.sock
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl cluster-info
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl get pods --all-namespaces
Master node setting
Reference : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kube
Worker Node Join
kubeadm join 192.168.56.60:6443 --token arh6up.usqi6daj82rj4rg2 
--discovery-token-ca-cert-hash sha256:12035aced64146fc7ccc5e3e737192c7209bc6bacc3fdb5b14400f6f9fd9
master node:
kubectl get pods --all-namespaces
kubectl get nodes -o wide
curl -k https://localhost:6443/version
Kubectl Autocomplete
K = kubectl
Source : https://kubernetes.io/docs/reference/kubectl/cheatsheet/
source <(kubectl completion bash) # set up autocomplete in bash into the current shell, bash-completion package should be installed first.
echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell.
vi /etc/profile 에 제일 아래, 다음 명령 추가
alias k=kubectl
complete -o default -F __start_kubectl k
추가 후, 바로 적용
source /etc/profile
Hello world
hello world
• Master node : deploy pod
• Worker node : check the pod is running
root@kopo:~# kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
deployment.apps/kubernetes-bootcamp created
root@kopo:~# k get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 0/1 1 0 12s
root@kopo:~# k get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 19s
root@kopo:~# k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 35s 10.244.1.2 worker01 <none> <none>
root@worker01:~# curl http://10.244.1.2:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6f6656d949-sdhqp | v=1
Terminology and concept
get
kubectl get all
kubectl get nodes
kubectl get nodes -o wide
kubectl get nodes -o yaml
kubectl get nodes -o json
describe
kubectl describe node <node name>
kubectl describe node/<node name>
Other
kubectl exec -it <POD_NAME>
kubectl logs -f <POD_NAME|TYPE/NAME>
kubectl apply -f <FILENAME>
kubectl delete -f <FILENAME>
Deployment method
• Daemon set : only single container per each node
• Replica set : control a number of container
• Stateful set : replica set + control sequence
<Pod>
Daemo
n
Daemon Set
Worker Node
#1
Worker Node
#1
Worker Node
#1
<Pod>
Daemo
n
<Pod>
Daemo
n
Kubectl practice
Make a pod
• k apply -f first-deploy.yml
• k get po
k get all
k describe po/kopotest
One container / one pod
apiVersion: v1
kind: Pod
metadata:
name: kopotest
labels:
type: app
spec:
containers:
- name: app
image: nginx:latest
Must be lower case
apiVersion: v1
kind: Pod
metadata:
name: kopotest-lp
labels:
type: app
spec:
containers:
- name: app
image: nginx:latest
livenessProbe:
httpGet:
<Liveness Probe Example>
k describe po/kopotest-lp
: Liveness probe failed: HTTP probe failed with statuscode: 404
k get po
k delete pod kopotest-lp
Liveness probe : check after boot up
Readiness probe : check before boot up
Make a pod
One container / one pod
Make a pod
• Healthcheck
k apply -f *.yml
One container / one pod
apiVersion: v1
kind: Pod
metadata:
name: wkopo-healthcheck
labels:
type: app
spec:
containers:
- name: app
image: nginx:latest
livenessProbe:
httpGet:
path: /
port: 80
root@kopo:~/project/ex01# k describe po/wkopo-healthcheck
Name: wkopo-healthcheck
Namespace: default
Priority: 0
Node: worker01/10.0.2.15
Start Time: Thu, 23 Jul 2020 11:40:37 +0000
Labels: type=app
Annotations: Status: Running
IP: 10.244.1.6
IPs:
IP: 10.244.1.6
Containers:
app:
Container ID: docker://064d9b4841dd4712c63669e770cfaf0ad5ba39ee9ca2d9ac4ed44b12224efc5b
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:0e188877aa60537d1a1c6484b8c3929cfe09988145327ee47e8e91ddf6f76f5c
Port: <none>
Host Port: <none>
State: Running
Started: Thu, 23 Jul 2020 11:40:42 +0000
Ready: True
Restart Count: 0
Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-h56q7 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-h56q7:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-h56q7
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 35s default-scheduler Successfully assigned default/wkopo-healthcheck to worker01
Normal Pulling 34s kubelet, worker01 Pulling image "nginx:latest"
Normal Pulled 30s kubelet, worker01 Successfully pulled image "nginx:latest"
Normal Created 30s kubelet, worker01 Created container app
Normal Started 30s kubelet, worker01 Started container app
root@kopo:~/project/ex01# k get po
NAME READY STATUS RESTARTS AGE
kopotest 1/1 Running 0 28m
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 8h
wkopo-healthcheck 1/1 Running 0 43s
참조 : https://bcho.tistory.com/1264
Make a pod
• K apply -f multi-container.yml
Multi container / one pod
apiVersion: v1
kind: Pod
metadata:
name: two-containers
spec:
restartPolicy: Never
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx-container
image: nginx
volumeMounts:
- name: shared-data
root@kopo:~/project/ex02# k get pod
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h
two-containers 1/2 NotReady 0 34m
root@kopo:~/project/ex02# k logs po/two-containers
error: a container name must be specified for pod two-containers, choose one of: [nginx-container debian-container]
root@kopo:~/project/ex02# k logs po/two-containers nginx-container
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
127.0.0.1 - - [23/Jul/2020:12:52:56 +0000] "GET / HTTP/1.1" 200 42 "-" "curl/7.64.0" "-"
Source : https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/
Make a pod
Multi container / one pod
Do this work-around if dns error occurs…
root@two-containers:/# cat > etc/resolv.conf <<EOF
> nameserver 8.8.8.8
> EOF
Source : https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/
k exec -it two-containers -c nginx-container -- /bin/bash
cd /usr/share/nginx/html/
more index.html
볼륨의 종류 참조 : https://bcho.tistory.com/1259
crictl
컨테이너 런타임 관리도구
• ctr -n k8s.io container list
• ctr -n k8s.io image list
• vi /etc/crictl.yaml
• crictl
• crictl pods
• crictl images
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
[참고] docker VS containerd
source : https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/#containerd-1-0-cri-containerd-end-of-li
Replicas
Replicas
• k apply -f repltest.yml
• k get rs
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# 케이스에 따라 레플리카를 수정한다.
replicas: 3
selector:
matchLabels:
tier: frontend
template:
Source : https://kubernetes.io/ko/docs/concepts/workloads/controllers/replicaset
Replicas
root@kopo:~/project/ex03-replica# k get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-jb9kl 1/1 Running 0 54s tier=frontend
frontend-ksbz8 1/1 Running 0 54s tier=frontend
frontend-vcpsm 1/1 Running 0 54s tier=frontend
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949
root@kopo:~/project/ex03-replica# k label pod/frontend-jb9kl tier-
pod/frontend-jb9kl labeled
root@kopo:~/project/ex03-replica# k get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-4jbf6 1/1 Running 0 4s tier=frontend
frontend-jb9kl 1/1 Running 0 3m6s <none>
frontend-ksbz8 1/1 Running 0 3m6s tier=frontend
frontend-vcpsm 1/1 Running 0 3m6s tier=frontend
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949
root@kopo:~/project/ex03-replica# k label pod/frontend-jb9kl tier=frontend
pod/frontend-jb9kl labeled
root@kopo:~/project/ex03-replica# k get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-jb9kl 1/1 Running 0 3m39s tier=frontend
frontend-ksbz8 1/1 Running 0 3m39s tier=frontend
frontend-vcpsm 1/1 Running 0 3m39s tier=frontend
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949
root@kopo:~/project/ex03-replica# k scale --replicas=6 -f repltest.yml
replicaset.apps/frontend scaled
root@kopo:~/project/ex03-replica# k get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-8vwl6 1/1 Running 0 5s tier=frontend
frontend-jb9kl 1/1 Running 0 4m20s tier=frontend
frontend-ksbz8 1/1 Running 0 4m20s tier=frontend
frontend-lzflt 1/1 Running 0 5s tier=frontend
frontend-vbthb 1/1 Running 0 5s tier=frontend
frontend-vcpsm 1/1 Running 0 4m20s tier=frontend
kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949
Delete label of one pod
Set the label
Add replica number
Source : https://kubernetes.io/ko/docs/concepts/workloads/controllers/replicaset
Replicas
k describe rs/<replicas name>
Deployment
Deployment
• K apply -f deploytest.yml
• kubectl get deployments
kubectl rollout status deployment.v1.apps/nginx-deployment
kubectl get rs
kubectl get pods --show-labels
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Deployment
• kubectl edit deployment.v1.apps/nginx-deployment
• kubectl rollout status deployment.v1.apps/nginx-deployment
• kubectl describe deployments
Deployment update
Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
In editor window, modify nginx version
1.14.2 -> 1.16.1
Deployment
• kubectl rollout history deployment.v1.apps/nginx-deployment
• 버전 업 배포 k apply -f ~.yml
• kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2
• kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=1
• kubectl describe deployment nginx-deployment
Deployment roll-back
Or
kubectl rollout undo deployment.v1.apps/nginx-deployment
Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Deployment
Scaling
Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
deployment
Rolling update
Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment
There are many strategies like
‘recreate’, ‘deadline seconds’ and so on.
Service
Service
• k apply -f clusterip.yml
cluster ip (internal network)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
Source : https://kubernetes.io/ko/docs/concepts/services-networking/connect-applications-service/
Creating a Service
So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly,
but what happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves.
A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality.
When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service,
and will not change while the Service is alive. Pods can be configured to talk to the Service,
and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.
Service
• k get all
• kubectl get pods -l run=my-nginx -o wide
• kubectl get pods -l run=my-nginx -o yaml | grep podIP
• kubectl get svc my-nginx
• kubectl describe svc my-nginx
• kubectl get ep my-nginx
• kubectl exec my-nginx-5dc4865748-rhfq8 -- printenv | grep SERVICE
cluster ip (internal network)
root@kopo:~/project/ex04-deployment# k get all
NAME READY STATUS RESTARTS AGE
pod/kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 1 23h
pod/my-nginx-5dc4865748-rhfq8 1/1 Running 0 36s
pod/my-nginx-5dc4865748-z7qkt 1/1 Running 0 36s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d19h
service/my-nginx ClusterIP 10.110.148.126 <none> 80/TCP 36s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubernetes-bootcamp 1/1 1 1 23h
deployment.apps/my-nginx 2/2 2 2 36s
NAME DESIRED CURRENT READY AGE
replicaset.apps/kubernetes-bootcamp-6f6656d949 1 1 1 23h
replicaset.apps/my-nginx-5dc4865748 2 2 2 36s
root@kopo:~/project/ex04-deployment# kubectl get pods -l run=my-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-5dc4865748-rhfq8 1/1 Running 0 60s 10.244.1.28 worker01 <none> <none>
my-nginx-5dc4865748-z7qkt 1/1 Running 0 60s 10.244.1.27 worker01 <none> <none>
root@kopo:~/project/ex04-deployment# kubectl get pods -l run=my-nginx -o yaml | grep podIP
f:podIP: {}
f:podIPs:
podIP: 10.244.1.28
podIPs:
f:podIP: {}
f:podIPs:
podIP: 10.244.1.27
podIPs:
root@kopo:~/project/ex04-deployment# kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.110.148.126 <none> 80/TCP 104s
root@kopo:~/project/ex04-deployment# kubectl describe svc my-nginx
Name: my-nginx
Namespace: default
Labels: run=my-nginx
Annotations: Selector: run=my-nginx
Type: ClusterIP
IP: 10.110.148.126
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.27:80,10.244.1.28:80
Session Affinity: None
Events: <none>
root@kopo:~/project/ex04-deployment# kubectl get ep my-nginx
NAME ENDPOINTS AGE
my-nginx 10.244.1.27:80,10.244.1.28:80 2m3s
root@kopo:~/project/ex04-deployment# kubectl exec my-nginx-5dc4865748-rhfq8 -- printenv | grep SERVICE
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
MY_NGINX_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT=443
MY_NGINX_SERVICE_HOST=10.110.148.126
Source : https://kubernetes.io/ko/docs/concepts/services-networking/connect-applications-service/
클러스터 IP로 접속 확인
• Pod의 Nginx 에서 서비스하는 index.html 파일을 로컬로 복사
k cp default/my-nginx-646554d7fd-gqsfh:usr/share/nginx/html/index.html ./index.html
• index.html을 편집하여 Pod간 index.html 파일 내용을 다르게 구분해 둔다.
• 편집한 index.html 파일을 Pod로 복사
k cp ./index.html default/my-nginx-646554d7fd-gqsfh:usr/share/nginx/html/index.html
• 해당 Pod로 진입하여 변경된 파일 확인
k exec -it my-nginx-646554d7fd-gqsfh -- /bin/bash
• 접속 확인
Pod <-> Local File Copy
그림출처: https://bcho.tistory.com/tag/nodeport
Service
Nodeport (expose network)
그림출처:
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true
&blogId=freepsw&logNo=221910012471
Service
• K apply -f nodeport.yml
• At worker node:
curl http://localhost:30101 -> OK
curl http://10.107.58.105 -> OK, service endpoint(k get ep my-nginx)
curl http://10.107.58.105:30101 -> X (nonsense)
curl http://10.244.1.115:30101 -> X(nonsense; service unreachable
to each pod’s endpoint as nodeport can only be access through
Node not Pod)
Nodeport (expose network)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
Reference: https://bcho.tistory.com/tag/nodeport
Service
• Nodeport, port, target port
Nodeport (expose network)
Source : https://stackoverflow.com/questions/49981601/difference-between-targetport-and-port-in-kubernetes-service-definition
Source : https://www.it-swarm-ko.tech/ko/kubernetes/kubernetes-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%a0%95%ec%9d%98%ec%97%90%ec%84%9c-targetport%ec%99%80-%ed%8f%ac%ed%8a%b8%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90/838752717/
Ingress
Ingress
• wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-
v1.7.1/deploy/static/provider/baremetal/deploy.yaml
• 상기 다운로드 파일을 아래와 같이 편집
• k apply -f deploy.yaml
https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal
 추가!
ingress test
Test.yml
root@kopo:~/project/ex08-ingress# k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-nginx <none> my-nginx.192.168.56.4.sslip.io 192.168.56.4 80 12m
test-ingress <none> * 192.168.56.4 80 13m
whoami-v1 <none> v1.whoami.192.168.56.3.sslip.io 192.168.56.4 80 11m
root@kopo:~/project/ex08-ingress#
If you got below error when executing “k apply -f test.yml”,
Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook
"validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.ingress-nginx.svc:443/extensions/v
service "ingress-nginx-controller-admission" not found
Then you might have to delete ValidatingWebhookConfiguration (workaround)
kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
Ingress
• K apply -f ingress.yml
Apply and test
root@kopo:~/project/ex08-ingress# k get all
NAME READY STATUS RESTARTS AGE
pod/my-nginx-694b8667c5-9dbdq 1/1 Running 0 9m31s
pod/my-nginx-694b8667c5-r274z 1/1 Running 0 9m31s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 83d
service/my-nginx NodePort 10.108.46.127 <none> 80:30850/TCP 9m31s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-nginx 2/2 2 2 9m31s
NAME DESIRED CURRENT READY AGE
replicaset.apps/my-nginx-694b8667c5 2 2 2 9m31s
root@kopo:~/project/ex08-ingress# k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
my-nginx <none> my-nginx.192.168.56.4.sslip.io 192.168.56.4 80 9m38s
root@kopo:~/project/ex08-ingress# k get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.110.64.145 <none> 80:31064/TCP,443:32333/TCP 80d
ingress-nginx-controller-admission ClusterIP 10.102.247.88 <none> 443/TCP 80d
root@kopo:~/project/ex08-ingress#
kind: Ingress
metadata:
name: my-nginx
annotations:
ingress.kubernetes.io/rewrite-target: "/"
ingress.kubernetes.io/ssl-redirect: "false"
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: my-nginx.192.168.56.61.sslip.io
http:
※ worker 노드에서 80 포트 방화벽 해제 필수 :
ufw allow 80/tcp
Tip & Trouble Shooting
Log search
• kubectl logs [pod name] -n kube-system
ex> kubectl logs coredns-383838-fh38fh8 -n kube-system
• kubectl describe nodes
When you change network plugin…
Pods failed to start after switch cni plugin from flannel to calico and then flannel
Reference : https://stackoverflow.com/questions/53900779/pods-failed-to-start-after-switch-cni-plugin-from-flannel-to-calico-and-then-f
When you lost token…
• kubeadm token list
• openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der
2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
• If you want to create new token;
$ kubeadm token create
kubeadm join 192.168.56.3:6443 --token iyees9.hc9x59uz97a71rio 
--discovery-token-ca-cert-hash sha256:a5bb90c91a4863d1615c083f8eac0df8ca8ca1fa571fc73a8d866ccc60705ace
CoreDNS malfunctioning
• https://www.it-swarm-ko.tech/ko/docker/kubernetes-클러스터에서-coredns가-실행되
지-않습니다/806878349/
• https://waspro.tistory.com/564
What should I do to bring my cluster up automatically after a host machine restart ?
Reference : https://stackoverflow.com/questions/51375940/kubernetes-master-node-is-down-after-restarting-host-machine
Cannot connect to the Docker daemon
• Error Message :
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker da
emon running?
• $sudo systemctl status docker
• $sudo systemctl start docker
• $sudo systemctl enable docker
Probably docker stopped
Pod connection error
• root@kopo:~/project/ex02# k exec -it two-containers -c nginx-container -- /bin/bash
error: unable to upgrade connection: pod does not exist
Conf 파일에
Environment="KUBELET_EXTRA_ARGS=--node-ip=<worker IP address>”
추가하고 서비스 재시작
Source : https://github.com/kubernetes/kubernetes/issues/63702
Nginx Ingress web hook error
Source : https://stackoverflow.com/questions/61365202/nginx-ingress-service-ingress-nginx-controller-admission-not-found
Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook
"validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.ingress-nginx.svc:443/extensions/v1beta1/ingresses?timeout=30s:
service "ingress-nginx-controller-admission" not found
Then you might have to delete ValidatingWebhookConfiguration (workaround)
kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission
root@kopo:~/project/ex08-ingress# k exec -it po/ingress-nginx-controller-7fd7d8df56-qpvlr -n ingress-nginx -- /bin/bash
bash-5.0$ curl http://localhost/users
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body { text-align:center;font-family:helvetica,arial;font-size:22px;
color:#888;margin:20px}
#c {margin:0 auto;width:500px;text-align:left}
</style>
</head>
<body>
<h2>Sinatra doesn&rsquo;t know this ditty.</h2>
<img src='http://localhost/__sinatra__/404.png'>
<div id="c">
Try this:
<pre>get &#x27;&#x2F;users&#x27; do
&quot;Hello World&quot;
end
</pre>
</div>
</body>
</html>
root@kopo:~/project/ex08-ingress# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.110.64.145 <none> 80:31064/TCP,443:32333/TCP 110m
ingress-nginx-controller-admission ClusterIP 10.102.247.88 <none> 443/TCP 110m
Ingress-nginx controller check if it is service properly
Nginx ingress controller - connection refused
Source : https://groups.google.com/forum/#!topic/kubernetes-users/arfGJnx
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
hostNetwork: true
Kubeadm reset
# docker 초기화
$ docker rm -f `docker ps -aq`
$ docker volume rm `docker volume ls -q`
$ umount /var/lib/docker/volumes
$ rm -rf /var/lib/docker/
$ systemctl restart docker
# k8s 초기화
$ kubeadm reset
$ systemctl restart kublet
# iptables에 있는 데이터를 청소하기 위해
$ reboot
Ref: https://likefree.tistory.com/13

k8s practice 2023.pptx

  • 1.
    Kubernetes Practice Dept. ofsmart finance Korea Polytechnics
  • 2.
    Requirements • We’ll make2 VMs, one is master node and the other is worker node. Each node need to be set as below • CPU : 2 core (minimum) • RAM : 3GB (minimum) • Storage: 30GB(minimum) • OS : Ubuntu 22.04 (preferred)
  • 3.
    Network setup • 1.Set a host network manager (menu -> file -> host network manager…) In virtual box
  • 4.
    Network setup • Adaptor1 : NAT • Adaptor 2: Host-Only Network In virtual box
  • 5.
    setup network infowhile installing
  • 6.
    Network setup • check vi/etc/netplan/00-installer-config.yaml NAT Host-Only Adapter Master Reference : https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/#network-plugin-requirem netplan apply
  • 7.
    Network setup • vi/etc/sysctl.d/k8s.conf • sysctl --system
  • 8.
    Network setup cat <<EOF| sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter
  • 9.
  • 10.
    hosts • vi /etc/hosts 192.168.56.60master 192.168.56.61 worker01
  • 11.
    hostname setting • Hostnamesetting in worker node • If worker’s hostname is equal to master, then you will see following error message on worker node when executing kubeadm join >> a Node with name ** and and status "Ready" already exists in the cluster. hostnamectl set-hostname worker01 vi /etc/cloud/cloud.cfg
  • 12.
    Requirements • Memory swapoff swapoff -a • • Check ports Docker https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ vi /etc/fstab
  • 13.
    VM 복제 worker node •check vi /etc/netplan/00-installer-config.yaml • hostnamectl set-hostname worker01 netplan apply
  • 14.
    [tip] virtual boxrange port forwarding 1. Vbox register(If needed) : VBoxManage registervm /Users/sf29/VirtualBox VMs/Worker/Worker.vbox 2. for i in {30000..30767}; do VBoxManage modifyvm "Worker" --natpf1 "tcp-port$i,tcp,,$i,,$i"; done https://kubernetes.io/docs/reference/networking/ports-and-protocols/ ufw allow "OpenSSH" ufw enable ufw allow 6443/tcp ufw allow 2379:2380/tcp ufw allow 10250/tcp ufw allow 10259/tcp ufw allow 10257/tcp ufw status master(control plane) node Worker node ufw allow "OpenSSH" ufw enable ufw status ufw allow 10250/tcp ufw allow 30000:32767/tcp ufw status Port Open
  • 15.
  • 16.
    Kubernetes setup Install containerd curl-fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null apt update apt install containerd.io systemctl stop containerd mv /etc/containerd/config.toml /etc/containerd/config.toml.orig containerd config default > /etc/containerd/config.toml vi /etc/containerd/config.toml SystemdCgroup = true systemctl start containerd systemctl is-enabled containerd systemctl status containerd
  • 17.
    Kubernetes setup Install kubernetes aptinstall apt-transport-https ca-certificates curl -y # curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - #echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list apt update apt install kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl # 패키지가 자동으로 업그레이드 되지 않도록 고정 kubeadm version kubelet --version kubectl version https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
  • 18.
    CNI(컨테이너 네트워크 인터페이스)플러그인 설치 mkdir -p /opt/bin/ curl -fsSLo /opt/bin/flanneld https://github.com/flannel-io/flannel/releases/download/v0.19.0/flanneld-amd64 chmod +x /opt/bin/flanneld lsmod | grep br_netfilter kubeadm config images pull
  • 19.
    Master node setting Kubeadminit Your ip address Reference : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kube kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.56.60 --cri-socket=unix:///run/containerd/containerd.sock
  • 20.
    mkdir -p $HOME/.kube cp-i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config kubectl cluster-info kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml kubectl get pods --all-namespaces Master node setting Reference : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kube
  • 21.
    Worker Node Join kubeadmjoin 192.168.56.60:6443 --token arh6up.usqi6daj82rj4rg2 --discovery-token-ca-cert-hash sha256:12035aced64146fc7ccc5e3e737192c7209bc6bacc3fdb5b14400f6f9fd9 master node: kubectl get pods --all-namespaces kubectl get nodes -o wide curl -k https://localhost:6443/version
  • 22.
    Kubectl Autocomplete K =kubectl Source : https://kubernetes.io/docs/reference/kubectl/cheatsheet/ source <(kubectl completion bash) # set up autocomplete in bash into the current shell, bash-completion package should be installed first. echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell. vi /etc/profile 에 제일 아래, 다음 명령 추가 alias k=kubectl complete -o default -F __start_kubectl k 추가 후, 바로 적용 source /etc/profile
  • 23.
  • 24.
    hello world • Masternode : deploy pod • Worker node : check the pod is running root@kopo:~# kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 deployment.apps/kubernetes-bootcamp created root@kopo:~# k get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE kubernetes-bootcamp 0/1 1 0 12s root@kopo:~# k get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE kubernetes-bootcamp 1/1 1 1 19s root@kopo:~# k get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 35s 10.244.1.2 worker01 <none> <none> root@worker01:~# curl http://10.244.1.2:8080 Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6f6656d949-sdhqp | v=1
  • 25.
  • 26.
    get kubectl get all kubectlget nodes kubectl get nodes -o wide kubectl get nodes -o yaml kubectl get nodes -o json describe kubectl describe node <node name> kubectl describe node/<node name> Other kubectl exec -it <POD_NAME> kubectl logs -f <POD_NAME|TYPE/NAME> kubectl apply -f <FILENAME> kubectl delete -f <FILENAME>
  • 27.
    Deployment method • Daemonset : only single container per each node • Replica set : control a number of container • Stateful set : replica set + control sequence <Pod> Daemo n Daemon Set Worker Node #1 Worker Node #1 Worker Node #1 <Pod> Daemo n <Pod> Daemo n
  • 28.
  • 29.
    Make a pod •k apply -f first-deploy.yml • k get po k get all k describe po/kopotest One container / one pod apiVersion: v1 kind: Pod metadata: name: kopotest labels: type: app spec: containers: - name: app image: nginx:latest Must be lower case apiVersion: v1 kind: Pod metadata: name: kopotest-lp labels: type: app spec: containers: - name: app image: nginx:latest livenessProbe: httpGet: <Liveness Probe Example> k describe po/kopotest-lp : Liveness probe failed: HTTP probe failed with statuscode: 404 k get po k delete pod kopotest-lp Liveness probe : check after boot up Readiness probe : check before boot up
  • 30.
    Make a pod Onecontainer / one pod
  • 31.
    Make a pod •Healthcheck k apply -f *.yml One container / one pod apiVersion: v1 kind: Pod metadata: name: wkopo-healthcheck labels: type: app spec: containers: - name: app image: nginx:latest livenessProbe: httpGet: path: / port: 80 root@kopo:~/project/ex01# k describe po/wkopo-healthcheck Name: wkopo-healthcheck Namespace: default Priority: 0 Node: worker01/10.0.2.15 Start Time: Thu, 23 Jul 2020 11:40:37 +0000 Labels: type=app Annotations: Status: Running IP: 10.244.1.6 IPs: IP: 10.244.1.6 Containers: app: Container ID: docker://064d9b4841dd4712c63669e770cfaf0ad5ba39ee9ca2d9ac4ed44b12224efc5b Image: nginx:latest Image ID: docker-pullable://nginx@sha256:0e188877aa60537d1a1c6484b8c3929cfe09988145327ee47e8e91ddf6f76f5c Port: <none> Host Port: <none> State: Running Started: Thu, 23 Jul 2020 11:40:42 +0000 Ready: True Restart Count: 0 Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3 Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-h56q7 (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-h56q7: Type: Secret (a volume populated by a Secret) SecretName: default-token-h56q7 Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 35s default-scheduler Successfully assigned default/wkopo-healthcheck to worker01 Normal Pulling 34s kubelet, worker01 Pulling image "nginx:latest" Normal Pulled 30s kubelet, worker01 Successfully pulled image "nginx:latest" Normal Created 30s kubelet, worker01 Created container app Normal Started 30s kubelet, worker01 Started container app root@kopo:~/project/ex01# k get po NAME READY STATUS RESTARTS AGE kopotest 1/1 Running 0 28m kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 8h wkopo-healthcheck 1/1 Running 0 43s 참조 : https://bcho.tistory.com/1264
  • 32.
    Make a pod •K apply -f multi-container.yml Multi container / one pod apiVersion: v1 kind: Pod metadata: name: two-containers spec: restartPolicy: Never volumes: - name: shared-data emptyDir: {} containers: - name: nginx-container image: nginx volumeMounts: - name: shared-data root@kopo:~/project/ex02# k get pod NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h two-containers 1/2 NotReady 0 34m root@kopo:~/project/ex02# k logs po/two-containers error: a container name must be specified for pod two-containers, choose one of: [nginx-container debian-container] root@kopo:~/project/ex02# k logs po/two-containers nginx-container /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Configuration complete; ready for start up 127.0.0.1 - - [23/Jul/2020:12:52:56 +0000] "GET / HTTP/1.1" 200 42 "-" "curl/7.64.0" "-" Source : https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/
  • 33.
    Make a pod Multicontainer / one pod Do this work-around if dns error occurs… root@two-containers:/# cat > etc/resolv.conf <<EOF > nameserver 8.8.8.8 > EOF Source : https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/ k exec -it two-containers -c nginx-container -- /bin/bash cd /usr/share/nginx/html/ more index.html 볼륨의 종류 참조 : https://bcho.tistory.com/1259
  • 34.
  • 35.
    컨테이너 런타임 관리도구 •ctr -n k8s.io container list • ctr -n k8s.io image list • vi /etc/crictl.yaml • crictl • crictl pods • crictl images runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock
  • 36.
    [참고] docker VScontainerd source : https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/#containerd-1-0-cri-containerd-end-of-li
  • 37.
  • 38.
    Replicas • k apply-f repltest.yml • k get rs apiVersion: apps/v1 kind: ReplicaSet metadata: name: frontend labels: app: guestbook tier: frontend spec: # 케이스에 따라 레플리카를 수정한다. replicas: 3 selector: matchLabels: tier: frontend template: Source : https://kubernetes.io/ko/docs/concepts/workloads/controllers/replicaset
  • 39.
    Replicas root@kopo:~/project/ex03-replica# k getpods --show-labels NAME READY STATUS RESTARTS AGE LABELS frontend-jb9kl 1/1 Running 0 54s tier=frontend frontend-ksbz8 1/1 Running 0 54s tier=frontend frontend-vcpsm 1/1 Running 0 54s tier=frontend kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949 root@kopo:~/project/ex03-replica# k label pod/frontend-jb9kl tier- pod/frontend-jb9kl labeled root@kopo:~/project/ex03-replica# k get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS frontend-4jbf6 1/1 Running 0 4s tier=frontend frontend-jb9kl 1/1 Running 0 3m6s <none> frontend-ksbz8 1/1 Running 0 3m6s tier=frontend frontend-vcpsm 1/1 Running 0 3m6s tier=frontend kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949 root@kopo:~/project/ex03-replica# k label pod/frontend-jb9kl tier=frontend pod/frontend-jb9kl labeled root@kopo:~/project/ex03-replica# k get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS frontend-jb9kl 1/1 Running 0 3m39s tier=frontend frontend-ksbz8 1/1 Running 0 3m39s tier=frontend frontend-vcpsm 1/1 Running 0 3m39s tier=frontend kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949 root@kopo:~/project/ex03-replica# k scale --replicas=6 -f repltest.yml replicaset.apps/frontend scaled root@kopo:~/project/ex03-replica# k get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS frontend-8vwl6 1/1 Running 0 5s tier=frontend frontend-jb9kl 1/1 Running 0 4m20s tier=frontend frontend-ksbz8 1/1 Running 0 4m20s tier=frontend frontend-lzflt 1/1 Running 0 5s tier=frontend frontend-vbthb 1/1 Running 0 5s tier=frontend frontend-vcpsm 1/1 Running 0 4m20s tier=frontend kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 0 10h app=kubernetes-bootcamp,pod-template-hash=6f6656d949 Delete label of one pod Set the label Add replica number Source : https://kubernetes.io/ko/docs/concepts/workloads/controllers/replicaset
  • 40.
  • 41.
  • 42.
    Deployment • K apply-f deploytest.yml • kubectl get deployments kubectl rollout status deployment.v1.apps/nginx-deployment kubectl get rs kubectl get pods --show-labels apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
  • 43.
    Deployment • kubectl editdeployment.v1.apps/nginx-deployment • kubectl rollout status deployment.v1.apps/nginx-deployment • kubectl describe deployments Deployment update Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/ In editor window, modify nginx version 1.14.2 -> 1.16.1
  • 44.
    Deployment • kubectl rollouthistory deployment.v1.apps/nginx-deployment • 버전 업 배포 k apply -f ~.yml • kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2 • kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=1 • kubectl describe deployment nginx-deployment Deployment roll-back Or kubectl rollout undo deployment.v1.apps/nginx-deployment Source : https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
  • 45.
  • 46.
    deployment Rolling update Source :https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment There are many strategies like ‘recreate’, ‘deadline seconds’ and so on.
  • 47.
  • 48.
    Service • k apply-f clusterip.yml cluster ip (internal network) apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 Source : https://kubernetes.io/ko/docs/concepts/services-networking/connect-applications-service/ Creating a Service So we have pods running nginx in a flat, cluster wide, address space. In theory, you could talk to these pods directly, but what happens when a node dies? The pods die with it, and the Deployment will create new ones, with different IPs. This is the problem a Service solves. A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.
  • 49.
    Service • k getall • kubectl get pods -l run=my-nginx -o wide • kubectl get pods -l run=my-nginx -o yaml | grep podIP • kubectl get svc my-nginx • kubectl describe svc my-nginx • kubectl get ep my-nginx • kubectl exec my-nginx-5dc4865748-rhfq8 -- printenv | grep SERVICE cluster ip (internal network) root@kopo:~/project/ex04-deployment# k get all NAME READY STATUS RESTARTS AGE pod/kubernetes-bootcamp-6f6656d949-sdhqp 1/1 Running 1 23h pod/my-nginx-5dc4865748-rhfq8 1/1 Running 0 36s pod/my-nginx-5dc4865748-z7qkt 1/1 Running 0 36s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d19h service/my-nginx ClusterIP 10.110.148.126 <none> 80/TCP 36s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kubernetes-bootcamp 1/1 1 1 23h deployment.apps/my-nginx 2/2 2 2 36s NAME DESIRED CURRENT READY AGE replicaset.apps/kubernetes-bootcamp-6f6656d949 1 1 1 23h replicaset.apps/my-nginx-5dc4865748 2 2 2 36s root@kopo:~/project/ex04-deployment# kubectl get pods -l run=my-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-5dc4865748-rhfq8 1/1 Running 0 60s 10.244.1.28 worker01 <none> <none> my-nginx-5dc4865748-z7qkt 1/1 Running 0 60s 10.244.1.27 worker01 <none> <none> root@kopo:~/project/ex04-deployment# kubectl get pods -l run=my-nginx -o yaml | grep podIP f:podIP: {} f:podIPs: podIP: 10.244.1.28 podIPs: f:podIP: {} f:podIPs: podIP: 10.244.1.27 podIPs: root@kopo:~/project/ex04-deployment# kubectl get svc my-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-nginx ClusterIP 10.110.148.126 <none> 80/TCP 104s root@kopo:~/project/ex04-deployment# kubectl describe svc my-nginx Name: my-nginx Namespace: default Labels: run=my-nginx Annotations: Selector: run=my-nginx Type: ClusterIP IP: 10.110.148.126 Port: <unset> 80/TCP TargetPort: 80/TCP Endpoints: 10.244.1.27:80,10.244.1.28:80 Session Affinity: None Events: <none> root@kopo:~/project/ex04-deployment# kubectl get ep my-nginx NAME ENDPOINTS AGE my-nginx 10.244.1.27:80,10.244.1.28:80 2m3s root@kopo:~/project/ex04-deployment# kubectl exec my-nginx-5dc4865748-rhfq8 -- printenv | grep SERVICE KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_SERVICE_HOST=10.96.0.1 MY_NGINX_SERVICE_PORT=80 KUBERNETES_SERVICE_PORT=443 MY_NGINX_SERVICE_HOST=10.110.148.126 Source : https://kubernetes.io/ko/docs/concepts/services-networking/connect-applications-service/
  • 50.
    클러스터 IP로 접속확인 • Pod의 Nginx 에서 서비스하는 index.html 파일을 로컬로 복사 k cp default/my-nginx-646554d7fd-gqsfh:usr/share/nginx/html/index.html ./index.html • index.html을 편집하여 Pod간 index.html 파일 내용을 다르게 구분해 둔다. • 편집한 index.html 파일을 Pod로 복사 k cp ./index.html default/my-nginx-646554d7fd-gqsfh:usr/share/nginx/html/index.html • 해당 Pod로 진입하여 변경된 파일 확인 k exec -it my-nginx-646554d7fd-gqsfh -- /bin/bash • 접속 확인 Pod <-> Local File Copy
  • 51.
    그림출처: https://bcho.tistory.com/tag/nodeport Service Nodeport (exposenetwork) 그림출처: https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true &blogId=freepsw&logNo=221910012471
  • 52.
    Service • K apply-f nodeport.yml • At worker node: curl http://localhost:30101 -> OK curl http://10.107.58.105 -> OK, service endpoint(k get ep my-nginx) curl http://10.107.58.105:30101 -> X (nonsense) curl http://10.244.1.115:30101 -> X(nonsense; service unreachable to each pod’s endpoint as nodeport can only be access through Node not Pod) Nodeport (expose network) apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 Reference: https://bcho.tistory.com/tag/nodeport
  • 53.
    Service • Nodeport, port,target port Nodeport (expose network) Source : https://stackoverflow.com/questions/49981601/difference-between-targetport-and-port-in-kubernetes-service-definition Source : https://www.it-swarm-ko.tech/ko/kubernetes/kubernetes-%ec%84%9c%eb%b9%84%ec%8a%a4-%ec%a0%95%ec%9d%98%ec%97%90%ec%84%9c-targetport%ec%99%80-%ed%8f%ac%ed%8a%b8%ec%9d%98-%ec%b0%a8%ec%9d%b4%ec%a0%90/838752717/
  • 54.
  • 55.
    Ingress • wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller- v1.7.1/deploy/static/provider/baremetal/deploy.yaml •상기 다운로드 파일을 아래와 같이 편집 • k apply -f deploy.yaml https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal  추가!
  • 56.
    ingress test Test.yml root@kopo:~/project/ex08-ingress# kget ingress NAME CLASS HOSTS ADDRESS PORTS AGE my-nginx <none> my-nginx.192.168.56.4.sslip.io 192.168.56.4 80 12m test-ingress <none> * 192.168.56.4 80 13m whoami-v1 <none> v1.whoami.192.168.56.3.sslip.io 192.168.56.4 80 11m root@kopo:~/project/ex08-ingress# If you got below error when executing “k apply -f test.yml”, Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.ingress-nginx.svc:443/extensions/v service "ingress-nginx-controller-admission" not found Then you might have to delete ValidatingWebhookConfiguration (workaround) kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - http: paths: - path: /testpath pathType: Prefix backend: service: name: test port: number: 80
  • 57.
    Ingress • K apply-f ingress.yml Apply and test root@kopo:~/project/ex08-ingress# k get all NAME READY STATUS RESTARTS AGE pod/my-nginx-694b8667c5-9dbdq 1/1 Running 0 9m31s pod/my-nginx-694b8667c5-r274z 1/1 Running 0 9m31s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 83d service/my-nginx NodePort 10.108.46.127 <none> 80:30850/TCP 9m31s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-nginx 2/2 2 2 9m31s NAME DESIRED CURRENT READY AGE replicaset.apps/my-nginx-694b8667c5 2 2 2 9m31s root@kopo:~/project/ex08-ingress# k get ingress NAME CLASS HOSTS ADDRESS PORTS AGE my-nginx <none> my-nginx.192.168.56.4.sslip.io 192.168.56.4 80 9m38s root@kopo:~/project/ex08-ingress# k get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.110.64.145 <none> 80:31064/TCP,443:32333/TCP 80d ingress-nginx-controller-admission ClusterIP 10.102.247.88 <none> 443/TCP 80d root@kopo:~/project/ex08-ingress# kind: Ingress metadata: name: my-nginx annotations: ingress.kubernetes.io/rewrite-target: "/" ingress.kubernetes.io/ssl-redirect: "false" kubernetes.io/ingress.class: "nginx" spec: rules: - host: my-nginx.192.168.56.61.sslip.io http: ※ worker 노드에서 80 포트 방화벽 해제 필수 : ufw allow 80/tcp
  • 58.
    Tip & TroubleShooting
  • 59.
    Log search • kubectllogs [pod name] -n kube-system ex> kubectl logs coredns-383838-fh38fh8 -n kube-system • kubectl describe nodes
  • 60.
    When you changenetwork plugin… Pods failed to start after switch cni plugin from flannel to calico and then flannel Reference : https://stackoverflow.com/questions/53900779/pods-failed-to-start-after-switch-cni-plugin-from-flannel-to-calico-and-then-f
  • 61.
    When you losttoken… • kubeadm token list • openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' • If you want to create new token; $ kubeadm token create kubeadm join 192.168.56.3:6443 --token iyees9.hc9x59uz97a71rio --discovery-token-ca-cert-hash sha256:a5bb90c91a4863d1615c083f8eac0df8ca8ca1fa571fc73a8d866ccc60705ace
  • 62.
  • 63.
    What should Ido to bring my cluster up automatically after a host machine restart ? Reference : https://stackoverflow.com/questions/51375940/kubernetes-master-node-is-down-after-restarting-host-machine
  • 64.
    Cannot connect tothe Docker daemon • Error Message : Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker da emon running? • $sudo systemctl status docker • $sudo systemctl start docker • $sudo systemctl enable docker Probably docker stopped
  • 65.
    Pod connection error •root@kopo:~/project/ex02# k exec -it two-containers -c nginx-container -- /bin/bash error: unable to upgrade connection: pod does not exist Conf 파일에 Environment="KUBELET_EXTRA_ARGS=--node-ip=<worker IP address>” 추가하고 서비스 재시작 Source : https://github.com/kubernetes/kubernetes/issues/63702
  • 66.
    Nginx Ingress webhook error Source : https://stackoverflow.com/questions/61365202/nginx-ingress-service-ingress-nginx-controller-admission-not-found Error from server (InternalError): error when creating "STDIN": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post https://ingress-nginx-controller-admission.ingress-nginx.svc:443/extensions/v1beta1/ingresses?timeout=30s: service "ingress-nginx-controller-admission" not found Then you might have to delete ValidatingWebhookConfiguration (workaround) kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission
  • 67.
    root@kopo:~/project/ex08-ingress# k exec-it po/ingress-nginx-controller-7fd7d8df56-qpvlr -n ingress-nginx -- /bin/bash bash-5.0$ curl http://localhost/users <!DOCTYPE html> <html> <head> <style type="text/css"> body { text-align:center;font-family:helvetica,arial;font-size:22px; color:#888;margin:20px} #c {margin:0 auto;width:500px;text-align:left} </style> </head> <body> <h2>Sinatra doesn&rsquo;t know this ditty.</h2> <img src='http://localhost/__sinatra__/404.png'> <div id="c"> Try this: <pre>get &#x27;&#x2F;users&#x27; do &quot;Hello World&quot; end </pre> </div> </body> </html> root@kopo:~/project/ex08-ingress# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.110.64.145 <none> 80:31064/TCP,443:32333/TCP 110m ingress-nginx-controller-admission ClusterIP 10.102.247.88 <none> 443/TCP 110m Ingress-nginx controller check if it is service properly
  • 68.
    Nginx ingress controller- connection refused Source : https://groups.google.com/forum/#!topic/kubernetes-users/arfGJnx apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: hostNetwork: true
  • 69.
    Kubeadm reset # docker초기화 $ docker rm -f `docker ps -aq` $ docker volume rm `docker volume ls -q` $ umount /var/lib/docker/volumes $ rm -rf /var/lib/docker/ $ systemctl restart docker # k8s 초기화 $ kubeadm reset $ systemctl restart kublet # iptables에 있는 데이터를 청소하기 위해 $ reboot Ref: https://likefree.tistory.com/13

Editor's Notes

  • #8 bridge 네트워크를 통해 송수신되는 패킷이 iptables 설정을 우회한다는 의미 컨테이너의 네트워크 패킷이 호스트머신의 iptables 설정에 따라 제어되도록 하는 것이 바람직하며 이를 위해서는 이 값을 1로 설정해야 한다
  • #12 https://github.com/kubernetes/kubernetes/issues/89512 https://github.com/kubernetes/kubernetes/issues/79779
  • #17 Cgroup : Control Group 다수의 Process가 포함되어 있는 Process Group 단위 Resource(cpu,mem,disk,nt) 사용량을 제한하고 격리시키는 Linux의 기능 Container의 Resource 제어에 사용
  • #18 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
  • #20 kubeadm init’ prechecks several things and installs the cluster control plane components. This may take several minutes. As a result of ‘kubeadm init’, at the end of a output contains 2 rows of information like this; Then, you can copy those lines and paste on worker terminal to run (above token expires 24hrs later)
  • #21 root@master:~/.kube# kubectl cluster-info Kubernetes control plane is running at https://192.168.56.60:6443 CoreDNS is running at https://192.168.56.60:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. root@master:~/.kube# kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml namespace/kube-flannel created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds created
  • #22 kubeadm join 192.168.56.60:6443 --token arh6up.usqi6daj82rj4rg2 \ --discovery-token-ca-cert-hash sha256:12035aced64146fc7ccc5e3e737192c7209bc6bacc3fdb5b14400f6f9fd9adfa [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
  • #25 K delete deployment ku~
  • #32 kubectl delete -f ./
  • #33 k describe pod/two-containers
  • #40  k get po -o wide
  • #41 test로 labels: tier의 value를 afrontend로 변경했었음
  • #50 At worker node : root@worker01:~# curl http://10.100.93.92 —> from kubectl describe svc my-nginx
  • #53 curl -k http://192.168.56.3:30101 839 k descrie svc my-nginx 840 k describe svc my-nginx 841 curl -k http://10.97.234.81:30101 842 curl -k http://localhost:30101 843 netstat -antp | grep 30101
  • #56 https://stackoverflow.com/questions/56915354/how-to-install-nginx-ingress-with-hostnetwork-on-bare-metal
  • #69 running on baremetal, ingress is working on service port, but on port 80 is not listening. https://github.com/kubernetes/kubernetes/issues/31307