Worker 내부 기본적으로 Docker 컨테이너 인터페이스를 사용하지만
쿠버네티스의 Container Runtime Interface (CLI) 를 통해 다양한 인터페이스 호환이 가능함
Master Node - ETCD Cluster (1) / kube-apiserver (2) / kube-controller Manager (3) / kube-scheduler (4)
Workder Node - kubelet (5) / kube-proxy (6)
▶ ETCD Cluster (1)
key-value store 형식으로 독자적인 형태로 다양한 데이터 보관 :2379 \\
ETCD 를 직접 구성하기 VS Kubeadm 으로 구성하기
▶ kube-apiserver (2)
가장 먼저 명령어를 관할 하는 부분
cat /etc/kubernetes/manifests/kube-apiserver.yaml
OR
cat /etc/systemd/system/kube-apiserver.service
ps -aux | grep kube-apiserver
▶ kube-controller Manager (3)
실시간으로 자원을 모니터링하면서 조절하는 부분
cat /etc/kubernetes/manifests/kube-controller-manager.yaml
OR
cat /etc/systemd/system/kube-controller-manager.service
ps -aux | grep kube-controller-manager
▶ kube-scheduler (4)
파드를 노드에 스케쥴링 결정 하는 부분
cat /etc/kubernetes/manifests/kube-scheduler.yaml
ps -aux | grep kube-scheduler
▶ kubelet (5)
각 노드에서 자원 관리 / Pod
kubelet 설치위해 다운 받아도 직접 설정 필요함
ps -aux | grep kubelet
▶ kube-proxy (6)
각 노드에서 서비스로 통신하기위해 룰 설정
kubeadm 설치 시 deamoset 으로 설정됨
Pod
기본적으로 노드 내부에 파드
파드 내부에 컨테이너
가용성을 높이기 위해선 파드 내부에 컨테이너 형식으로 노드안에 같은 파드를 여러개 생성 & 노드와 파드 함께 추가 생성
파드에 다수의 컨테이너가 위치하는 경우에는 각 개체들이 서로 같은 네트워크/스토리지 공유하며 파드가 죽으면 다 함께 운명을 맞이함 (컨테이너 종류는 다른편)
kubectl run nginx --image=nginx
nginx 이름을 가진 nginx 이미지를 가진 파드 생성
kubet get pods
파드 불러오기
kubectl describe pod pod-name
파드 자세히 불러오기
kubectl create -f pod.yaml
kubectl apply -f pod.yaml
yaml 로 파일 생성하기
kubectl delete pod pod-name
파드 삭제하기
yaml 기본 예시
apiVersion: v1
kind: Pod
metadata: #파드 주관적인 정의 (파드 이름이나 레이블 등등)
name: nginx
spec: #컨테이너 객관적인 정의 (컨테이너 구성 요소 이름이나 이미지 등등)
containers:
- name: nginx
image: nginx:1.14.2
- name: busybox #멀티 컨테이너의 경우 추가 방식
Replication Controller & Replica Set
파드 1개로 운용하거나 가용성을 위해 여러개를 운용할때 정해둔 개수만큼 꼭 돌아가게 하기 위해 조절해주는 역할
Label 로 모니터링할 아이들을 인식함
스케일링(파드 개수 늘리기)
kubectl replace -f rs.yaml
파일 자체 수정후 변경
kubectl scale --replicas=3 -f rs.yaml
kubectl scale --replicas=3 replicaset rs-name
명령어로 수정
pod 의 Label
metadata:
name: label-demo
labels:
environment: production
Replicaset 의 Label
Replication Controller 에선 필수가 아님 + apiversion 도 다름
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
environment: production
Deployment
*yaml 파일은 Replicaset 과 큰 차이는 없음 / kind: Deployment
한번에 수정 적용이나 업그레이드 할때 용이하게 사용되어 Replicaset 보다 더 큰범위에서 파드들을 적용시킴
Namespaces
리소스 사용에 구분을 지어 원활하게 관리하고자 하는 네임텍 같은 역할
기본적으론 Defalut Namespace 로 지정되어 있음
Namespace 별로 할당량을 미리 지정해놓고 싶을때 - Resource Quota
apiVersion: v1
kind: ResourceQuota
metadata:
name: disable-cross-namespace-affinity
namespace: foo-ns
spec:
hard:
pods: "0"
개수 세기
# kubectl get pods | wc -l
Service
자원과 통신하기 위해 필요한 구성요소
서비스는 다른 자원에 비해 비교적 유연하게 작동하기 때문에 파드/노드 범위에 상관없이 사용가능
Node Port - 노드 범위에서 접근 가능한 포트 (30000~32767) 노드 포트의 경우 selector 값에 파드 레이블 지정해서 파드도 같이 설정필요
#curl http://192.168.0.2:30008
ClusterIP - 노드 내부 구성요소의 포트 (기본값) (80)
Loadbalancer - 노드의 가용성을 높이기위해 통신을 할당 및 분배할때 필요한 포트/ 단일의 ip 주소로 접근 가능
노드포트에서 type 만 달라지지만 loadbalnace 역할이 작동하기 위해선 3rd party 기능 연동 사용 필요
Node Port 의 예시
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: MyApp
ports:
- port: 80
# By default and for convenience, the `targetPort` is set to
# the same value as the `port` field.
targetPort: 80
# Optional field
# By default and for convenience, the Kubernetes control plane
# will allocate a port from a range (default: 30000-32767)
nodePort: 30007
Lables
자원별로 구별 가능쉽게 레이블링 하는 역할
Selector
레이블링 한 값을 찾아주는 역할 / 필터링
Taints&Tolerations
노드에 Taint + 파드에 Tolerations 설정
노드라는 갑옷에 Tolerations 값을 가진 파드만 무기로 접근 가능
Node Selector
원하는 노드를 간략히 지정 가능
Node Affinity
Node Selector 와 비슷하나 조금 더 자세히 정의 가능
파드에 Node Affinity 설정으로
갈고리로 원하는 노드에 부착
Node Affinity + Taints&Tolerations 함께 사용함으로 정확히 지정 설정 가능
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
Resource Requirement & Limits
LimitRange / CPU & Memory
해당 kind 설정 이후 생성되는 자원에만 적용 가능
Resoucequota
DaemonSets
각 파드 생성마다 기본적으로 1개씩 갖게끔 하는 것
모니터링이나 로그 확인용으로 용이
kube-proxy & weave-net
* kube-scheduler 과는 상관 없음
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
Static Pods
api server 에 상관없이 노드 범위에서 kubelet 이 독단적으로 파드 생성에 관여할 수 있음
/etc/kubernetes/manifests
yaml 파일로 static pod 생성
kubelet service 파일에 경로 확인 혹은
kubeconfig 파일 확인
* kube-scheduler 과는 상관 없음
ps -ef | grep /usr/bin/kubelet
--from-file
Multiple Schedulers
kubectl get events -o wide
kubectl logs customer-scheduler --name-space=kube-system
Monitoring
CPU&Memory 확인
#kubectl top node
#kubectl top pod
로그 확인
#kubectl logs -f pod-name (+container-name)
Rolling Updates
#kubectl rollout status deployment/my-deploy
#kubectl rollout history deployment/my-deploy
#kubectl rollout undo deployment/my-deploy
이미지 변경 방법
kubectl apply -f my-deploy.yaml
or
kubectl set image deployment/my-deploy ningx-name=nginx:1.7.1
Commands and Arguments
Docker 의 ENTRYPOINT ["sleep"] --- > K8S 의 command : ["sleep"]
Docker 의 CMD ["5"] --- > args : ["5"]
Environmental variables
1) 기본형
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
2) Configmap 형
configmap 우선 생성 후 pod 에 삽입
#kubeclt create configmap config-name --from-literal=key=value
or
#kubeclt create configmap config-name --from-file=filename
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
# Define the environment variable
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
# The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
name: special-config
# Specify the key associated with the value
key: special.how
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
3) Secret 형
(Encrpytion 되지 않고 문자 변형만 되서 저장됨)
#kubeclt create screte generic secret-name --from-literal=key=value
or
#kubeclt create screte generic secret-name --from-file=filename
하지만 secret 는 변형되어 보관해야 안전하므로
echo -n '숨길문자' | base 64
echo -n '풀어낼문자' | base 64 --decode
k get secret
k describe secret
k get secret secret-name -o yaml
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
spec:
containers:
- name: envars-test-container
image: nginx
envFrom:
- secretRef:
name: test-secret
OS Upgrade
업그레이드 중 유용하게 사용될
kubectl drain node01
임시적으로 해당 노드의 파드를 다른곳에 위치시키고 사용 못하게 함
kubetl cordon node02
임시적으로 해당 노드를 사용 못하게 함
kubectl uncordon02
해당 노드를 다시 사용하게 함
업그레이드 하는 방법은 한단계씩 점진하여 하는것이 좋음
kubeadm 으로 하는경우
kubeadm upgrade plan
kubeadm updgrade apply
1.마스터 노드 업그레이드 -> 2.워커 노드 업그레이드
adm 툴 업그레이드
apt-get upgrade -y kubeadm=1.12.0-00
클러스터 업그레이드
kubeadm upgrade apply v1.12.0
kubectl drain controlplane
kubelet 업그레이드
apt-get upgrade -y kubelet=1.12.0-00
systemctl restart kubelet
wokrder 노드 업그레이드 (각 노드)
kubectl drain node01 (마스터)
ap-get upgrade -y kubeadm=1.12.0-00
ap-get upgrade -y kubelet=1.12.0-00
kubeadm upgrade node config --kubelet-version v1.12.0
systemctl restart kubelet
kubectl uncordon node01 (마스터)
ETCD Back Up
ETCD Backup VS API kubectl Backup
Save - Restore 작업
( #export ETCDCTL_API=3
#etcdctl version )
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
snapshot save <backup-file-location>
service kube-apiserver stop
systemctl daemon-reload
service etcd restart
service kube-apiserver start
Security
Who 누가 접근 & What 무엇을 관리
누가 접근
User & Serviceaccount(kube로 생성가능)
가장 기본적으로 auth-file 생성해서 path 를 지정해서 가져오게끔 설정 하는 방법
롤 설정
curl -v -k https://localhost:6443/api/v1/pods -u "user1:password123"
TLS
Symmetric Encryption - 같은키로 보내고 받아서 사용
Asymmetric Encryption - Private & Public Key 로 사용
같은 키를 보내면 위험성이 크므로
해당 키를 Asymmetric 방식으로 전송하여 중요한 정보와 key 를 주고받음
하지만 이방식에서도 허점이 있으므로
Sertificate 을 통해 증명서로 안전한 key 라는것을 인증
CA(Certificate Authority)
CSR(Ceriticate Signing Request) 을 통해 CA 의 인증을 발급받음
Server Certificate - Kube API & ETCD & Kubelet
Client Ceritificate - Admin & Kube Scheduler & Kube Controller Manager & Kube-Proxy 모두 ~ API 서버로 연결 & Kube API ( 연결 ~ ETCD & Kubelet )
CA
1. ca.key 키 생성
openssl genrsa -out ca.key 2048
2. ca.csr (사인 리퀘스트)
openssl req -new -key ca.key -subj \ "/CN=KUBERNETES-CA" -out ca.csr
3. ca.crt (사인)
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
curl https://kube-apiserver:6443/api/v1/pods --key admin.key --cert admin.crt --cacert ca.crt
OR
kube-config 파일에 구성
모든 자원의 Certificate 생성에는 ca.crt 파일 복제본이 필요함
Adimin
1. admin.key 키 생성
openssl genrsa -out admin.key 2048
2. admin.csr (사인 리퀘스트)
openssl req -new -key admin.key -subj \ "/CN=kube-admin" -out admin.csr
3. admin.crt (사인)
openssl x509 -req -in admin.csr -CA ca.crt -CAkey ca.key -out admin.crt
ETCD Cert -> etcd path 구성 변경 필요
API Server Cert
openssl genrsa -out apiserver.key 2048
openssl req -new -key apiserver.key -subj \ "/CN=kube-apiserver" -out admin.csr #-config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -out apiserver.crt
Kubelet Node
kubelet-config 파일에 구성 (각 노드)
Cert 파일 자세히 확인 하는법
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
서비스 로그 확인
journalctl -u etcd.service -l
kubectl logs etcd-master
docker ps -a
dokcer logs #containerID
Run crictl ps -a command to identify the kube-api server container.
Run crictl logs container-id command to view the logs.
Certificates API
(Controller manager 에 의해 관리됨)
openssl genrsa -out admin.key 2048
openssl req -new -key jane.key -subj \ "/CN=jane" -out jane.csr
jane-csr.yaml
(cat jane.csr | base64)
kubectl get csr
kubectl certificate approve jane
base64 -w 0
공백 없이 생성
Kubeconfig
cirl https://hello:6443/api/v1/pods
--key admin.key
--cert admin.crt
--cacert ca.crt
k get pods
--server hello:6443
--client-key admin.key
--client-certificate admin.crt
--certificate-authority ca.crt
k get pods
--kubeconfig config
kubeconfig file 의 정보 (
--server hello:6443
--client-key admin.key
--client-certificate admin.crt
--certificate-authority ca.crt )
Kubeconfig file 에는 Cluster & Contexts & Users
로 구성되어 있어 Cluster 에는 크게 목적
Users 에는 사용자
Contect 는 어디 사용자가 무슨 목적으로 사용하지는지 연결
* config file 은 따로 생성할 필요는 업슴
.kube/config
kubectl config view
특정 파일의 contecxt 이용
k config use-context --kubeconfig=/root/my-kube-config research
API Groups
/apis 아래 항목으로 각 자원 존재
curl https://kube-master:6443/version
curl https://kube-master:6443/api/vi/pods
curl http://localhost:8001 -k (kubeproxy 로 credential 사용 안해도 됨)
authority
ARBC - 유저당 추가해야함으로 관리하기 까다로움
RBAC - Rule 을 지정해서 유저를 넣어주기만 하면 됨으로 관리하기 수월함
Role 우선 생성 -> RoleBinding 생성 하여 유저를 추가
#kubectl auth can-i create nodes 형식으로 접근 재확인
or --as dev-user --namespace test
--authorization-mode=Node,RBAC,Webhook OR AlwaysAllow
Cluster Role 은 일반적인 Role 과 달리 노드 & PV 단계 범위에서 역할을 지정해주는것
Service Account
kubernets 의 자원이 아닌 제3자의 서비스가 권한을 갖는것
default SA 가 아닌 본인이 만든 SA 를 추가하려면 Pod 에 직접 추가 (serviceAccountName & automountServiceAccountToken: false)
Image Security
docker login private-image.io
docker run private-image.io/apps/internal-app
image: private-image.io/apps/internal-app
kubectl create secret docker-registry regcred
--docker-server=
--docker-username=
--docer-password=
--docker-email=
imagePullSecrets:
-name : regcred
Security Context
Pod 범위 vs Container 범위
k exec ubuntu-sleeper -- whoami
* Capabilities 섹션은 container 범위 아래 에서만 사용 가능
NetworkPolicy
Ingress & Egress
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
Volumes
Storage Drivers VS Volume Drivers
Storage Drivers - Volume mount (기본 저장소에서) & Bind mount (지정 저장소에서)
Volume Drivers - 보통 3rd party 볼륨에 마운트
CSI (Container Storage Interface)
파드가 생성되고 제거될때 보통 데이터도 함께 제거되므로
파드 파일 내에 Volume 지정 & 컨테이너에 해당 Volume 연결 해서 생성
*노드별로 모두 같은 path 에두면 관리하기에 어려우므로 3rd party 연결하여 사용
Persistent Volume
으로 각각 파드에 정의하는대신 한번에 관리 할 수 있게끔 미리 볼륨을 생성 해 놓음
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
이때 사용자가 PV 사용하기 위해 Persistent Volume Claim
1:1 관계로 PVC 라는 사용에의해 이를 만족시킬 수 있는 PV 를 찾는 과정 (Binding)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
PVC 삭제후 PV 의 상태는 (Remain/Deleted/Recycle) 옵션을 선택할 수 있음
PVC 는 파드에 일반 볼륨을 넣는것 처럼 따로 넣어줘야함
Storage Class 를 pvc 에 사용한다면 자동으로 생성하므로 따로 pv 를 생성할 필요 없음
** kubeadm 설치
cat /etc/*-release
runtime 설치
kubeadm 설치
master 노드 initialize
kubeadm init --apiserver-advertise-address=@ --pod-network-cidr=@
Networking
Switch
같은 ip 주소 범위 내에서 서로 통신
#ip link
(eth0 같은 스위치로 서로 접속)
Routing
다른 ip 주소간에 통신 가능하게 연결
#routing
(routing table 확인 가능)
#ip route add default via 192.168.2.1
(원하는 목적지로 가기 위해 gateway add 해주는 설정)
echo 1 > /proc/sys/net/ipv4/ip_forward
/etc/sysctl.conf 의 net.ipv4.ip_forward=1 로 영구 변경 가능
DNS
cat >> etc/hosts
cat /etc/resolv.conf (dns 서버에 저장)
Network Namespaces
ip netns exec red ip link
ip -n red link
ip link add verth-red type veth peer name veth-blue
ip link set veth-red netns red / ip -n red link del veth-red
ip link set veth-blue netns blue
ip -n red addr add 192.168.15.1 dev veth-red
ip -n blue addr add 192.168.15.2 dev veth-blue
ip link add v-net-0 type bridge
ip link set dev v-net-0 up
p link add verth-red type veth peer name veth-red-br
ip link set veth-red netns red
ip link set veth-red master v-net-0
ip -n red addr add 192.168.15.1 dev veth-red
ip -n red link set veth-red up
ip addr add 192.168.15.5/24 dev v-net-0 (master)
CNI (Container Network Interface)
Port - Kube-api(6443), kubelet(10250) kube-scheduler(10259)
kube-controller-manager(10257),etcd(2379),etcd client(2380)
nodeport services(30000-32767)
Pod Networking
net-script.sh 에 네트워크 연결 정의
#ps -aux | grep kubelet 으로 kubelet 의 cni 확인 가능
ls /opt/cni/bin
ls /etc/cni/net.d
CNI - DHCP / Host-local 기능
Service Networking
kube-proxy 가 iptable 생성 관리
#iptables -L -t nat
# cat /var/log/kube-proxy.log
curl http://web-service.apps.svc.clister.local
다른 namespace 에 있는 svc 에 접근
# cat /etc/coredns/Corefile -> kubectl get configmap -n kube-system
# cat /var/lib/kubelet/config.yaml 에서 dns 서버 주소 확인 가능
Ingress
프록시 & 로드밸런싱을 비롯한 다양한 역할을 수행해주는 역할
Nignx 와 같은 Ingress controller 설정 이후 Ingress Resources 설정
1) Path 로 설정
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-backend
spec:
defaultBackend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: static-assets
rules:
- http:
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: icon-assets
2) Host 로 설정
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
Application Trouble Shooting
서비스 & 파드 연결성 및 정보 확인 - 보통 웹 페이지 서비스 에서 오류 확인
Controlplan Trouble Shooting
서비스 상태 확인 - 보통 컨트롤 플레인 자원 작동 오류로 manifest 확인 혹은 로그 확인 필요
#service kube-apiserver status
#service kube-controller-manager status
#service kube-scheduler status
#service kubelet status
#service kube-proxy status
로그 확인
#kubectl logs kube-apiserver-master -n kube-system
#sudo journalctl -u kube-apiserver
Worker Node Trouble Shooting
노드 확인
#top
#df -h
#service kubelet status
#sudo journalctl -u kubelet
#openssl x509 -in /var/lib/kubelet/worker-1.crt -text
'Kubernates' 카테고리의 다른 글
쿠버네티스 따배씨 강의 (1) | 2024.01.24 |
---|---|
Kubernetes 쿠버네티스 CKA (Udemy 강의#04) (0) | 2023.07.26 |
Kubernetes 쿠버네티스 CKA (Udemy 강의#03) (0) | 2023.07.21 |
Kubernetes 쿠버네티스 CKA (Udemy 강의#02) (0) | 2023.07.14 |
Kubernetes 쿠버네티스 CKA (Udemy 강의#01) (0) | 2023.07.07 |