203. Prerequisite - Docker Networking

도커를 사용하면 여러가지 네트워킹 옵션이 존재한다.

None

도커를 none 네트워크 옵션으로 실행하면 그 어떤 네트워크랑 연결되지 않는다. 

외부로 접근 불가 

멀티 컨테이너로 만들어도 서로 통신 못한다.

host

호스트 네트워킹을 하면 컨테이너가 호스트의 네트워크에 연결되어 사용가능하다.

80번포트를 사용하는 앱을 배포하면 이용 가능할 것이다. 특별한 포트 포워딩 없이 사용가능

똑같이 컨테이너를 생성해도 같은 호스트 ,포트 네트워크를 동시에 공유할 수 없다. 

 

Bridge

bridge 모드로 생성하는 경우 사설네트워크가 생성된다.

172.17.0.0 을 기본으로 갖고 컨테이너가 추가될때 마다 ip를 부여받는다.

도커가 설체되면 bridge라는 사설 네트워크를 설치한다.

docker 에서 볼 때는 bridge 이지만 호스트에서는 docker0라는 이름으로 생성된다.

호스트가 ip link add docker0 type bridge 한 것처럼 docker가 사설 네트워크를 만든다.

ㅂ지난 시간에 본 가상 스위치

브릿지 네트워크는 인터페이스와 같으면서도 컨테이너,네임스페이스 안에서는 스위치 역할을 한다. 

docker 0 는 down 상태이며 172.17.0.1/24 ip 를 갖는다.

docker run nginx 로 컨테이너를 실행 후

ip netns 검색 

docker inspect로 확인하면 netns 가 생긴 것을 알 수 있다.

컨테이너와 브릿지 네트워크 docker0를 어떻게 연결 시킬까? 

docker0 인터페이스 vethbblc343@if7

vethbb~의 위치는 당연히 docker0에 있다 

컨테이너 netns 에서 link 명령을 하면 인터페이스를 확인할 수 있다.

컨테이너의 네트워크 인터페이스는 eth0@if8 이다.

컨테이너의 addr 을 확인해보면 ip 를 배정 받았다고 뜬다.

172.17.0.3/16

컨테이너가 추가될때마다 가상 인터페이스도 추가된다. 

nginx는 웹프로그램이라서 80번 포트를 갖는다.

도커 내부에서 컨테이너에 접속하면 가능하지만 외부에서는 접속불가능하다.

그래서 도커 컨테이너를 실행할때 포트포워딩 옵션을 넣어줘야한다. 

8080으로 들어오면 80 포트로 이동 

192.168.1.0:8080 으로 접속 가능해진다. 

도컨도 iptables 명령과 같은 효과 

똑같이 iptables 가 생성된 것을 확인할 수 있다. 


204. Prerequisite - CNI 

이전에 배운 것

도커도 사실 비슷한 원리다. 

rkt, mesos, k8s 다 비슷한 방식을 따른다. 

어차피 중복되는 내용인데 통합시키면 어떨까? 

bridge 로 묶었다.

bridge 명령어로  netns 에 있는 컨테이너를 연결시킬 수 있다.

bridge add <cid> <namespace> 

이다.

cni 로 쉽게 구성할 수 있다.

cni 규칙들 

플러그인 (프로그램들) 의 규칙

cni 규칙과 플러그인 규칙을 지켜야한다.

cni는 여러 플러그인을 지원한다. 

도커는 cni를 갖지 않고 독립적으로 cnm 을 갖는다. 

도커도 네트워크를 생성하고 브릿지로 연겨하면 된다. 


205. Cluster networking

IP & FQDN

마스터 노드와 워커 노드 각각의 ip, 인터페이스,호스트네임, 맥어드레스를 갖는다.

마스터노드의 kube-api 와 통신한다.

kubelet은 10250 포트를 듣는다. 

컴포넌트들의 포트번호

마스터 노드끼리 소통시에도 사용

Ports and Protocols | Kubernetes

 

Ports and Protocols

When running Kubernetes in an environment with strict network boundaries, such as on-premises datacenter with physical network firewalls or Virtual Networks in Public Cloud, it is useful to be aware of the ports and protocols used by Kubernetes components.

kubernetes.io

포트 번호가 있다.

기본적인 네트워크 명령들


207. Practice Test - Explore Kubernetes Environment

1. How many nodes are part of this cluster?

Including the controlplane and worker nodes.

2개

 

2. What is the Internal IP address of the controlplane node in this cluster?

192.6.192.12

 

3. What is the network interface configured for cluster connectivity on the controlplane node? 

 

node-to-node communication

 

ip a 명령어

eth0 이다. 

 

4. What is the MAC address of the interface on the controlplane node?

02:42:c0:06:c0:0c

 

5. What is the IP address assigned to node01?

192.6.192.3

 

6. What is the MAC address assigned to node01?

 

ip a 로 하면 확인 불가능하다.

 

워커 노드는 마스터 노드와 같은 인터페이스를 사용한다. 

eth0 를 통해서 mac addr 를 찾자.

 

7. We use Containerd as our container runtime. What is the interface/bridge created by Containerd on this host?

cni0

 

8. What is the state of the interface cni0?

 

up

 

9. If you were to ping google from the controlplane node, which route does it take?

default 가 172.25.0.1 게이트웨이를 사용

 

10. What is the port the kube-scheduler is listening on in the controlplane node?

 

10259 를 쓴다. 

 

netstat -nplt

 

11. Notice that ETCD is listening on two ports. Which of these have more client connections established?

2379

 

12. Correct! That's because 2379 is the port of ETCD to which all control plane components connect to. 2380 is only for etcd peer-to-peer connectivity. When you have multiple controlplane nodes. In this case we don't.

 

 


209. Pod networking

쿠버네티스 파드들은 어떻게 통신할까?

Networking Model

모든 파드들은 ip를 가지고 파드들은 다른 파드와 통신가능하다. 

nat 없이 

수 많은 네트워킹 솔루션

지난 시간에 했던거 복습해보자

마스터, 워커 상관없이 노드들이 연결되어있다. 

노드들에 각자 netns 가 있다.

브릿지 네트워크를 생성한다.

ip link add v-net-0 type bridge 

브릿지 네트워크 켜기 

ip link set dev v-net-0 up

브릿지 네트워크에 ip 부여하기

ip addr add 10.244.1.1/24 dev v-net-0

net-script.sh 파일을 만들어서 스크립트화 할 수 있다.

 

컨테이너 (netns 안의) 와 브릿지 네트워크 연결되었다.

파란 파드에서 보라색 파드에 접속하고 싶다면?

ping 은 안간다. 

라우터 추가해야 하나?

먼저 노드 단에서 라우터를 추가한다. 

ip route add 10.244.2.2 via 192.168.1.12

이제 ping 응답이 가능해진다.

노드단에서 브릿지 네트워크 ip 의 라우터를 다 추가한다.

모든 노드에서 라우터를 일일히 추가하는 것보다 라우터에서 정의하는것이 좋다. 

하나의 가상 네트워크 10.244.0.0/16

cni가 쉽게 해준다.

노드에 컨테이너가 생기면 kubelet이 확인하고 명령을 실행한다.


210. CNI in kubernetes

선수 지식

cni 규칙 

 

Configuring CNI

CNI 구성하기 

View kubelet options

kubelet에서 cni 옵션을 볼 수 있다. 

opt/cni/bin 폴더에서 여러 플러그인을 확인 가능

/etc/cni/net.d 에서 어느 플러그인이 사용될지 보여준다.

플러그인 구성파일이다. 

 


211. CNI weave

weaveworks는 cni 플러그인 중 하나이다. 

다른 컨테이너로 패킷 보내기 

라우팅 테이블을 사용하는데  더 좋은 방법이 없을까?

 

사무실이라고 가정하고 

office 1에서 office 3 로 보낼때 

 

알아서 잘 가겠지?

노드가 많아진다면? 

 

운송회사에 위임하자

weaverworks 직원을 각 나라에 상주 시킨다. 

각각의 직원들 통신망을 갖고 있다.

컨테이너에서 패킷을 보내려고하면

에이전트가 패킷을 가로채고 

패킹하고 

weaverworks 가 대신 보내준다.

마찬가지로 weaveworks가 서비스, 에이전트를 노드에 심는다. 

 

에이전트끼리 각자 네트워크를 형성한다. 

컨테이너에서 패킷을 보낼려고 하면 에이전트가 가로채서 보낸다. 

Deploy Weave

kubectl apply 를 통해서 weave 데몬을 생성할 수 있다. 

log 를 통해 트러블 슈팅


212. Practice Test - Explore CNI

1. Inspect the kubelet service and identify the container runtime endpoint value is set for Kubernetes.

 

 

ps aux | grep kubelets 

 

 --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock 

 

2. What is the path configured with all binaries of CNI supported plugins?

ls /opt/cni/bin 

이 경로에 모든  플러그인이 있다. 

 

 

3. Identify which of the below plugins is not available in the list of available CNI plugins on this host?

 

cisco

 

4. What is the CNI plugin configured to be used on this kubernetes cluster?

/etc/cni/net.d 

현재 사용중인 플러그인이 뜬다.

 

 

5. What binary executable file will be run by kubelet after a container and its associated namespace are created?

 

flannel 이 실행된다.

 


214. Practice Test - Deploy Network Solution

 1.  In this practice test we will install weave-net POD networking solution to the cluster. Let us first inspect the setup.

We have deployed an application called app in the default namespace. What is the state of the pod?

not running

 

 

2. Inspect why the POD is not running.

 

ip 할당 문제

 

3. Deploy weave-net networking solution to the cluster.

 

NOTE: - We already have provided a weave manifest file under the /root/weave directory.

원래는 weavenet github에서 가져와야한다. 

 


196. Networking - Section Introduction

이번 챕터는 배워야하는 선수 지식이 좀 많다.

 

 

198. Prerequisite - Switching Routing

네트워킹 파트를 공부하는데 있어 필요한 선수지식

Switcing, routing, dns, network namespace, docker networking 

 

Switching

두개의 호스트를 연결할려면 무엇이 필요할까? 

스위치에 연결해야한다. 스위치에 연결하기 위해선 각 호스트 인터페이스가 필요하다. 

ip link 명령어로 인터페이스를 확인할 수 있다.

eth0 라는 인터페이스를 사용한다.

스위치의 ip 주소가 192.168.1.0 이라고 가정하고 

ip addr add 로 호스트에 ip를 할당해보자

호스트 a 가 b로 ping 을 날리면 통신이 된다. 

Routing

비슷한 다른 네트워크 통신할려면 어떻해야할까?

192.168.1.11 에서 192.168.2.10 으로 통신할려면?

두 네트워크를 잇기 위해서 라우터를 사용한다. 

라우터도 마찬가지로 두 네트워크에 ip를 할당한다.

192.168.1.1과 192.168.2.1

b에서 c 로 패킷을 보내려고 할때 라우터의 위치는 어떻게 알까?

라우터는 네트워크에 있는 또 다른 디바이스로 인식된다. 어떻게 구분하는가

 

Gateway

 

게이트웨이가 있어야 외부 네트워크로 나갈 수 있다. 

 

호스트 b 에서 routes 명령을 해도 아무런 정보가 없다.

게이트웨이가 구성 안된 상태라서 외부에 접속 할 수 없다.

route 를 추가해줘야한다.  

2번 네트워크 스위치 ip 192.168.2.0 을   네트워크  1 라우터 ip 192.168.1.1 을 통해

(라우터를 등록하는 과정)

 

라우터가 등록되었다.

 

네트워크 2 에서 네트워크 1에 접속하고 싶으면 마찬가지로 라우터를 등록해야한다.

다른 네트워크로 가고 싶을때마다 라우터에 등록해야한다면 엄청나게 복잡할 것이다.

그대신

라우터가 인터넷 게이트웨이를 가졌다고 생각하고 default 라우터로 지정한다. 

default 대신에 0.0.0.0 로 표기해도 된다.

모든 네트워크를 의미

만약 네트워크 2에서 네트워크1 로 가는 라우터, 외부 인터넷 접속을 하는 라우터를 분리하고 싶다면

 

192.168.1.0 으로 가능 라우터 하나

0.0.0.0 외부로 가능 라우터 하나 

두개를 등록한다.

a,b,c 호스트가 있고 

a,b 같은 스위치 b,c 같은 스위치에 있다.

스위치로부터 ip를 부여받고 

b는 두개의 ip를 배정받는다. 

a가 c 와 통신하고 싶다면 어떻해야하는가?

 

호스트a 192.168.1.5 에서 ping 을 날려보자 

192.168.2.5 로 보내면 접속불가이다.

라우터가 없기 때문에 어떻게 가는지 모른다. 

먼저 호스트 a에서 route를 추가한다.

 192.168.2.0 스위치로 가는 라우터는 192.168.1.6 

a에서 c로 패킷을 보내고 c 가 응답을 하기 위해 

마찬가지로 192.168.1.0 네트워크로 가기 위해 192.168.2.6 네트워크에 연결한다. 

이제 호스트 a에서 ping은 보내지지만 응답이 없다? 

 

By default, in Linux, packets are not forwarded from one interface to the next.

 

다른 인터페이스끼리 한번에 패킷이 전달 되지 않는다고 한다. ( 리눅스 보안 때문?)

호스트 b 는 eth0, eth1 두개의 인터페이스를 가지고 있다. 

cat /proc/sys/net/ipv4/ip_forward 를 실행하면 0 의 값을 가진다.

해당 값을 1로 바꾼다. 

이제 다른 인터페이스라도 패킷 전달이 가능해진다.

ping 응답 가능

리부트하면 초기화 되기 때문에 /etc/sysctl.conf 로 가서 값을 변경하면 값이 유지된다.

 

명령어 정리

 

ip link - 인터페이스 확인

ip addr add - ip 할당하기

ip route - 라우터 확인하기

ip route add - 라우터 추가하기

cat /proc/sys/net/ipv4/ip_forward - 다른 인터페이스끼리 패킷 전달 허용 

 


199. Prerequisite - DNS

호스트 a와 호스트 b 가 있다. 

a에서 ping 날리면 응답이 오지만 호스트 네임 db 로 지정하고 보내면 모른다.

etc/hosts 파일에 192.168.1.11 은 db 라고 등록하고 ping db를 날리면 응답이 온다.

문제는 여기서 정한 이름이 호스트 a에서만 정해진 약속이라는 점

b의 호스트 네임을 변경해도 여전히 db 에 접속하능하고 

google.com 이름으로 정해도 핑이 보내진다.

 

Name Resolution

이름을 함부로 정한 것을 name Resolution 이라고 한다. 

호스트 c 가 추가된다면 etc/hosts 파일을 세번 수정해야한다. 

호스트가 많이 추가되면 지옥이다.

하나의 ip가 변경되면 변경을 수도 없이 해야한다.

모든 호스트의 etc/hosts 를 수정하는 것이 아닌 해당 역할을 중앙에서 처리하는 하나의 서버에 위임한다.

DNS

이제 모든 호스트이 dns 서버에 접속한다!

대신 모든 호스트의 /etc/resolv.cof 파일에 nameserver 정보가 담긴다.

pind db로 핑을 날릴 수도 있다. 

 

이제 /etc/hosts 파일을 일일히 수정할 필요없다. 

test 용 서버를 두고 싶을때 하나의 호스트의 etc/hosts 파일만 수정하고 해당 호스트에서만 접속하게 한다. 

이런 용도도 있다.

 

이름이 중첩됬을때는?

호스트 a 에 192.168.1.115 를 test로 

dns 서버에 192.168.1.116 이 test로 

같은 이름인 경우에는...

먼저 local  을 선택하고 접속이 불가하면 dns의 경로로 간다. 

우선 순위를 바꾸고 싶다면

/etc/nsswithc.conf 를 수정한다.

files 는 로컬 dns

순서를 바꾸면 dns 먼저 탐색하게 할 수 있다. 

etc/hosts, nameserver 둘 다 없는 도메인을 입력하면 접속 실패가 뜬다. 

.8nameserver 에 구글이 운영하는 공용 네임서버 8.8.8.8 에 등록하거나 

dns 서버에 forward all t0 8.8.8.8 을 입력하여 외부로 보낼 수 있다.

이제 외부로 갈 수 있다.

Domain Names

top level domain

맨 뒤에 오는 거 

 

google 앞에 오는 www, drive , email 이런 건 서브 도메인이라고 한다.

apps.google.com 을 접속한다고 가정하면

먼저 local dns는 google이 뭔지도 모른다. 

. root DNS 로 접근한다. 

.com 등의 탑 레벨 도메인으로 간후 

google dns 로 간다. 

google dns 에서 apps 가 누군지 확인하면 216.58.221.78 의 ip 주소가 나온다. 

해당 주소를 로컬 캐시에 저장하고  다음번 접속시 저장된 ip를 사용하여 빠르게 접속한다. 

 

 Record Types

 

nslookup

 

nslookup은 로컬 etcd/hosts 파일을 확인하지 않는다. dns서버만 쿼리한다. 

ping 대신 lookup, dig 으로 통신 상태 확인 가능하다. 

 

 

dig


201. Prerequisite - Network Namespaces

 

리눅스 네트워크 네임스페이스에 대해 배워볼거다. 

집을 방으로 분리하듯이 호스트는 네임스페이스를 이용하여 격리시킨다.

컨테이너를 네임스페이스로 감싼다.

컨테이너 안에서 ps aux 

호스트에서 ps aux 에서

프로세스 root 를 똑같이 감시할 수 있으나 다른 프로세스 id를 갖는다. 

(호스트 관리자는 네임스페이스안의 프로세스도 볼 수 있다.)

 

Network Namespace

호스트가 lan 과 연결될때 routing 테이블 과 arp 테이블을 갖는다.

네임스페이스 안에 컨테이너를 생성

컨테이너를 라우팅 테이블에 대한 정보를 어떻게 알고 통신할까?

컨테이너도 가상 인터페이스와 라우팅, arp 테이블을 갖는다!

Create Network NS

in netns add  명령어로 netns 를 추가한다.

Exec in network ns

ip link 로 인터페이스를 확인 할 수 있다. 

netns 로 들어가서 인터페이스를 확인 할려면?

ip netns exec red ip link

ip -n red link

 

exec 으로 접속해서 확인하거나 -n 옵션으로 확인하거나

호스트에서는 인터페이스 두개 다 확인가능하고 

netns 로 들어가서 확인하면 한개만 확인가능하다.

 

arp 테이블을 확인할때도 마찬가지 

호스트에서는 다 확인가능하지만

netns 에선 해당 arp 만 확인가능

라우팅 테이블도 똑같다. 

 

두개의 netns 링크

다른 두개의 netns 인터페이스를 연결하고 싶다면 ? 

먼저 호스트에서 가상 인터페이스를 두개 만든다. 

ip link add veth-red type veth peer name veth-blue

veth 하나를 netns 로 옮긴다.

ip link set veth-red netns red

나머지 veth를 netns로 옮긴다.

ip link set veth-red netns blue

네임스페이스 인터페이스에 ip를 부여한다.

ip -n red addr add 192.168.15.1 dev veth-red

마지막으로 link set up 명령을 통해 인터페이스를 사용 가능하게 만든다 .

ip -n red link set veth-red

핑을 날리거나 arp 테이블을 확인할 수 있다.

호스트에서 arp 를 날리면 netns 의 arp, 인터페이스를 확인할 수 없다.

 

netns 가 여러개라면?

netns 가 여러개라면 위의 작업을 수동으로 하기 힘들 것이다.

대신 가상 스위치를 구성하는 것이 효율적이다. 

Virtual Switch 만들기

리눅스 브릿지, 오픈 스위치 등을 사용할 수 있다.

 

Linux Bridge

호스트에서 bridge 타입 가상 인터페이스를 만든다. 

ip link add v-net-0 type bridge

호스트에서 ip link 하면 인터페이스로 확인 가능하다. 

down 상태 

 

ip link set dev v-net-0 up 으로 인터페이스를 켠다. 

 

스위치에 모두 연결하기 전에 이전에 만든 link를 없애준다. 

ip -n red link del veth-red

인터페이스를 가상의 인터페이스와 링크한다.

ip link add veth-red type veth peer name veth-red-br

veth-red-br 은 이름만 존재

인터페이스를 netns 로 이동시키고

ip link set veth-red netns red

나머지 가상의 인터페이스를 가상 스위치에 설치한다.

ip link set veth-red-br master v-net-0

블루도 마찬가지

인터페이스에 ip를 부여한다.

ip -n red addr add 192.168.15.1 dev veth-red

마지막으로 인터페이스를 켠다

ip -n red link set veth-red up

 

4개의 host 다 연결되었다고 가정

호스트에서 netns red 의 ip 192.168.15.1 로 ping 때리면 안간다.

같은 네임스페이스가 아니기 때문

호스트에서 가상 스위치에 ip를 부여한다.

ip addr add 192.168.15.5/24 dev v-net-0

 

기존에 다른 netsns 에 ip를 부여했기 때문에 5번이 아닐까 싶네

스위치도 하나의 디바이스로 인식하기 때문에 ip를 가진다.

이제 호스트에서 red netns 로 ping 이 보내진다. 

가상 스위치로 라우팅 되서 가능한 것 같다.

해당 네트워크는 네임스페이스 안에 있기 때문에 외부로 접근할 수 없다.

외부로 나갈려면 호스트의 포트를 통해서 나가야한다.

외부의 192.168.1.3 으로 접속할려면 어떻게 해야 하는가

블루 netns 에서 192.168.1.3 에 접속해보자 

ip netns exec blue pin 192.168.1.3

라우트 명령으로 라우팅 확인해보자

ip netns exec blue route

가상 스위치로 가는 라우터만 가지고 있다.

네트워크 접속 불가라고 뜬다.

 

어떻게해야할까

가상 스위치에 연결된 가상 인터페이스가 호스트에 있는 또 다른 인터페이스라고 생각하면 된다. 

블루 netns 에서 192.168.1.3 으로 가능 라우터를 추가할려면 

ip netns exec blue ip route add 192.168.1.0/24 via 192.168.15.5 

라우터를 추가한다. 

스위치 192.168.1.0 으로 가는데 있어 가상 스위치 인터페이스의 ip는 게이트웨이가 되어준다. 

이제 블루 netns 에서 192.168.1.3 으로 ping 을 날리면 가지만 응답이 없다. 

(리눅스에선 다른 인터페이스끼리 한번에 패킷 전달이 안된다. ... 인 줄 알았으나...)

 

블루 netns 에선 192.168.1.3 까지 라우팅 경로를 알고 있으나 

192.168.1.3 입장에서는 어느 경로로 응답해야하는지 정보가 없다.

 

호스트에 

iptables -t nat -A POSTROUTING -s 192.168.15.0/24 -j MASQUERADE 

를 추가한다.

해당 패킷을 받으면 호스트로부터 받은 패킷이라고 생각한다.(netns 로부터 온것이 아닌)

이제 응답을 받을 수 있다.

스위치가 인터넷과 연결되어있고

블루 netns 에서 8.8.8.8 로 접속할려고 하면 실패한다.

라우터 등록이 안되어있기 때문에

 

default 게이트웨이를 설정함으로써 해결할 수 있다.

외부 인터넷으로부터 응답을 받을 수 있다.

호스트에서 블루netns 로 핑을 보내면 가지만 외부 호스트 192.168.1.3 에서 보내면 접근 불가이다.

호스트에서 포트 포워딩 하는 방법이 있다.

ip tables -t nat -A PREROUTING --dport 80 --to-destination 192.168.15.2:80 -j DNAT 

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: claim-log-1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Mi

179. Storage - Section Introduction

여러가지 스토리지 옵션에 대해서 배워보자 

 

 

180. Introduction to Docker Storage

도커의 스토리지가 어떻게 동작하는지 먼저 알아보자 

Docker Storage

스토리지 드라이버, 볼륨 드라이버로 나뉜다. 

 


181. Storage in Docker

File System

docker 호스트의 파일 시스템

Layered architecture

읽고넘어가

 

레이어 형식이 라서 엔트리포인트는 용량이 없다

비슷한 내용으로 도커 빌드를 할 때 중복되는 레이어는 다시 생성하지 않는다. 
소스 코드와 엔트리포인트만 업데이트한다. 

공간 절약! & 빠른 실행

엔트리 포인트까지 업데이트한 것이 이미지 레이어이다.

이미지 레이어는 read only 로서 변경할려면 다시 초기화 해야한다. 

 

빌드후 run 하면 컨테이너가 생긴다. - 컨테이너 레이어 

컨테이너가 제거되면 컨테이너 레이어도 제거된다. 

 

Copy on write

 

이미지 레이어의 뭔가 하고 싶다면 컨테이너 레이어로 복사한 후 작성하라

 

컨테이너 레이어 삭제하면 데이터 모두 사라진다. 

volumes

데이터를 보존하고 싶다면?

1. 볼륨을 생성하고

2. 컨테이너 생성할 때 마운트 옵션으로 

볼륨 마운팅

 

이제 컨테이너가 사라져도 데이터가 남아있다. 

 

컨테이너 생성전에 볼륨 생성안했다면? 

 

도커가 볼륨을 자동으로 생성해준다.

bind mount

다른 경로와 연결

 

요즘은 v 옵션 대신 이렇게 사용

Storage drivers

 


182. Volume Driver Plugins in Docker

스토리지 드라이버 

볼륨 드라이버 플러그인

 다 다르다. 

도커에서 실행시 특정 볼륨 드라이버를 고를 수 있다.


183. Containter Storage Interface

container 는 cri

네트워크는 cni 

스토리지는 csi

인터페이스로 통신한다.

csi는 쿠버네티스 뿐만 아니라 다른 오케스트레이션 에서도 사용된다. 

 


185. Volumes

컨테이너에서 데이터는 컨테이너가 죽으면 같이 사라진다. 

컨테이너를 볼륨에 연결하면 데이터를 유지할 수 있다.

Volumes & Mounts

랜덤 숫자를 생성하는 파드를 만든다.

volumes에 마운트할 디렉토리를 명시한다.(호스트의)

volumeMounts 에는 컨테이너의 마운트할 경로를 작성한다.

컨테이너가 사라져도 데이터는 볼륨에 남아있다.

Volume Types

노드가 많아질 경우 다 똑같은 호스트 경로를 쓰면 비효율 적이다. 

쿠버네티스는 다양한 스토리지를 지원한다. 

 

ebs 에 담자 

 


186. Persistent Volumes

파드가 많아지면 스토리지 구성이 어렵다. 

 

persistent volume is a cluster-wide pool of storage volumes configured by an adminstrator

PV- 여러 파드들이 쓸 수 있는 클러스터 단위의 스토리지

여기에 요청 pvc 를 해야한다?

 

Persistent Volume 만들기 

pv를 먼저 구성한다. 


187. Persistent Volume Claims

pv와 pvc를 별개다.

관리자는 pv 를 만들고 사용자는 pvc를 만든다 .

pv와 pvc를 정렬하고 쿠버네티스가 매치되는 것과 바인딩한다. 

여러가지 모드도 고려해야함.

pvc 와 매치되는 pv 가 없으면 해당pvc는 pending 상태가 된다. 

pvc 생성하기

생성하자마자 pending 상태가 된다. 

쿠버네티스가 매칭되는 pv를 찾는다. 

매칭되면 bound 가 된다.

 

pvc를 제거 옵션

persistentVolumeReclaimPolicy -pvc 제거시 옵션

retain - pv는 남지만 다른 요청으로 재사용될 수 없음.

delete- pv도 삭제

recycle - 볼륨안의 데이터만 삭제

 


188. Using PVCs in PODs

    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      containers:
        - name: myfrontend
          image: nginx
          volumeMounts:
          - mountPath: "/var/www/html"
            name: mypd
      volumes:
        - name: mypd
          persistentVolumeClaim:
            claimName: myclaim

pod, deploy, rs 등 pvc를 쓰고 싶다면 spec 아래에 volumes 

pvc 옵션을 추가해서 사용한다. 

 

 


189. Practice Test - Persistent Volumes and Persistent Volume Claims

1. We have deployed a POD. Inspect the POD and wait for it to start running.

2. The application stores logs at location /log/app.log. View the logs.

 

You can exec in to the container and open the file:
kubectl exec webapp -- cat /log/app.log

 

애플리케이션 로그 저장하는 곳

 

 

3. If the POD was to get deleted now, would you be able to view these logs.

 

no

 

4. Configure a volume to store these logs at /var/log/webapp on the host.

Name: webapp
Image Name: kodekloud/event-simulator
Volume HostPath: /var/log/webapp
Volume Mount: /log
apiVersion: v1
kind: Pod
metadata:
  name: webapp
spec:
  containers:
  - name: event-simulator
    image: kodekloud/event-simulator
    env:
    - name: LOG_HANDLERS
      value: file
    volumeMounts:
    - mountPath: /log
      name: log-volume

  volumes:
  - name: log-volume
    hostPath:
      # directory location on host
      path: /var/log/webapp
      # this field is optional
      type: Directory

 

5. Create a Persistent Volume with the given specification.

Volume Name: pv-log
Storage: 100Mi
Access Modes: ReadWriteMany
Host Path: /pv/log
Reclaim Policy: Retain

6. Let us claim some of that storage for our application. Create a Persistent Volume Claim with the given specification.

 

Volume Name: claim-log-1
Storage Request: 50Mi
Access Modes: ReadWriteOnce

7. What is the state of the Persistent Volume Claim?

pending

 

8. What is the state of the Persistent Volume?

available

 

9. Why is the claim not bound to the available Persistent Volume?

 

access 모드 차이 때문

 

10.

Update the Access Mode on the claim to bind it to the PV.

Delete and recreate the claim-log-1.

 

pvc access mode 

readWriteMany 로 변경

 

11.  You requested for 50Mi, how much capacity is now available to the PVC?

여전히 100mi 사용가능

 

12.

Update the webapp pod to use the persistent volume claim as its storage.

 

Replace hostPath configured earlier with the newly created PersistentVolumeClaim.

 

13. What is the Reclaim Policy set on the Persistent Volume pv-log?

 

14.  What would happen to the PV if the PVC was destroyed?

 

The PV is not deleted but not available

 

 

15. Try deleting the PVC and notice what happens.

If the command hangs, you can use CTRL + C to get back to the bash prompt OR check the status of the pvc from another terminal

terminating 상태에 걸린다.

 

16. Why is the PVC stuck in Terminating state?

 

The PVC was still being used by the webapp pod when we issued the delete command. Until the pod is deleted, the PVC will remain in a terminating state.

webapp pod 가 아직 사용하고 있기 때문 파드가 삭제될때까지 대기중 

17.

Let us now delete the webapp Pod.

Once deleted, wait for the pod to fully terminate.

 

18. What is the state of the PVC now?

deleted

 

19. What is the state of the PV now?

released


193. Storage Classes 

지난 시간에 배운 pv, pvc 그리고 pod 에서 pvc 사용하기를 배웠다 .

Static Provisioning

pv 를 처음 구성할때 수동으로 기입해줘야한다. (여기선 외부 클라우드를 예시로 들었다.) 

static 프로비저닝이라고 한다.

당연히 이게 귀찮으니.... 

Dynamic Provisioning

pv 대신 storageClass를 사용할 거다. 

기존에 pv-pvc-pod 이렇게 연결되있었다. 

sc를 쓸거면 sc-pvc-pod  이렇게 연결 가능하다. 

pvc에서 sc를 쓸 수 있게 storageClassName 을 추가한다.

여기서 중요한 건 

sc 에 연결되어도 결국 pv 는 생성한다.

pv를 수동으로 생성안할 뿐 pv 랑은 여전히 연결된다.!!! 

Storage Class

여러 회사의 스토리지 클래스를 사용할 수 있으며 여러 옵션이 존재한다.

예를 들면 이런거

1. How many StorageClasses  exist in the cluster right now?

 

 

 

2. How about now? How many Storage Classes exist in the cluster?

3개

 

3. What is the name of the Storage Class  that does not support dynamic  volume provisioning?

local-storage 

provisioner 에서 no-provisioner 이다.

 

4. What is the Volume Binding Mode  used for this storage class (the one identified in the previous question)?

waitForFirstConsumer

 

5. What is the Provisioner  used for the storage class called portworx-io-priority-high ?

portworkvolume

 

6. Is there a PersistentVolumeClaim  that is consuming the PersistentVolume  called local-pv ?

no 

 

7. Let's fix that. Create a new PersistentVolumeClaim by the name of local-pvc that should bind to the volume local-pv.

Inspect the pv local-pv for the specs.

8. What is the status of the newly created Persistent Volume Claim?

pending 

 

9. Why is the PVC in a pending state despite making a valid request to claim the volume called local-pv?

Inspect the PVC events.

Normal WaitForFirstConsumer 12s (x8 over 111s) persistentvolume-controller waiting for first consumer to be created before binding

 

waitForFirstConsummer는 사용하지 않으면 pv 에 고정되지 않는다.

사용을 기다리는 중

 

10. The Storage Class called local-storage  makes use of VolumeBindingMode  set to WaitForFirstConsumer . This will delay the binding and provisioning of a PersistentVolume until a Pod using the PersistentVolumeClaim is created.

 

11. Create a new pod called nginx with the image nginx:alpine. The Pod should make use of the PVC local-pvc and mount the volume at the path /var/www/html.

The PV local-pv should in a bound state.

 

 

12. What is the status of the local-pvc  Persistent Volume Claim now?

13. Create a new Storage Class called delayed-volume-sc that makes use of the below specs:

provisioner: kubernetes.io/no-provisionervolumeBindingMode: WaitForFirstConsumer

 


167. Image Security

Image

예시 여기 이미지 nginx 는 어디서 왔을까?
.
docker 레지스트리 library 에서 가져온다.

Private Repository

private 레포지토리에서 가져올 수 있다.

먼저 private-registry.io 에 로그인 해야한다. 

image 에 전체 경로를 써야한다.

쿠버네티스가 어떻게 private 레포지토리에 인증할 수 있을까? 

워커노드의 도커 런타임에 어떻게 인증을 전달할 수 있을까 ?

-> secret 을 이용한다.

파드 정의에 secret이 들어간다.


168. Practice Test - Image Security 

1. What secret type must we choose for docker registry?

docker-registry 를 사용한다. 

 

 

2. We have an application running on our cluster. Let us explore it first. What image is the application using?

nginx 알파인

 

3.  We decided to use a modified version of the application from an internal private registry. Update the image of the deployment to use a new image from myprivateregistry.com:5000

The registry is located at myprivateregistry.com:5000. Don't worry about the credentials for now. We will configure them in the upcoming steps.

image 앞에 경로를 추가

4. Are the new PODs created with the new images successfully running?

작동 안된다 credential 문제인듯 

 

5.

Create a secret object with the credentials required to access the registry.

Name: private-reg-cred
Username: dock_user
Password: dock_password
Server: myprivateregistry.com:5000
Email: dock_user@myprivateregistry.com

 

 

 

6. Configure the deployment to use credentials from the new secret to pull images from the private registry

 

deployment 에 secret 을 쓸 수 있게 하자 .

 

Pull an Image from a Private Registry | Kubernetes

 

Pull an Image from a Private Registry

This page shows how to create a Pod that uses a Secret to pull an image from a private container image registry or repository. There are many private registries in use. This task uses Docker Hub as an example registry. 🛇 This item links to a third party

kubernetes.io

 

image 밑에 imagePullsecrets 로 넣자 .

 

7. Check the status of PODs. Wait for them to be running. You have now successfully configured a Deployment to pull images from the private registry.

잘돌아간다. 

 


170. Pre-requisite - Security in Docker

컨테니어와 호스트는 같은 커널을 공유한다. 

컨테이너의 네임스페이스는 밖으로 못나가지만 호스트 단의 네임스페이스는 컨테이너도 다 볼 수 있다. 

 

컨테이너 안에서 ps 명령어로 확인하면 하나의 프로세스만 뜨지만. 

 

호스트 단에 ps 명령어로 확인하면 다 나온다.

여기서는 root 의 pid 가 다르게 나올뿐 (컨테이너에서는 pid 1 이었다.)

마찬가지로 호스트 단의 root  유저와 컨테이너의 root 유저는 다르다 .

root 유저의 권한 어마무시해

권한을 주고 싶다면 --cap-add 명령을 하면 된다 .

또는 cap-drop 으로 권한을 제거할 수 있다. 

privileged 로 모두 가능하게 할 수 있다. 

 


171. Security contexts

도커에 유저를 추가하거나 커널 기능을 주거나.

쿠버네티스도 마찬가지

 

파드레벨
컨테이너 레벨

runAsUser 또는 capabity  등 이용가능


172. Practice Test - Security Contexts

1. What is the user used to execute the sleep process within the ubuntu-sleeper pod?

In the current(default) namespace.

파드에 접속한 후 whoami

 

 

2.

Edit the pod ubuntu-sleeper to run the sleep process with user ID 1010.

Note: Only make the necessary changes. Do not modify the name or image of the pod.

 

 

3. A Pod definition file named multi-pod.yaml is given. With what user are the processes in the web container started?

The pod is created with multiple containers and security contexts defined at the Pod and Container level.

오류 인가 안뜬다??

 

1002

 

4. With what user are the processes in the sidecar container started?

The pod is created with multiple containers and security contexts defined at the Pod and Container level.

명시 안되었으니 파드 단위 1001 

 

5.

Update pod ubuntu-sleeper to run as Root user and with the SYS_TIME capability.

Note: Only make the necessary changes. Do not modify the name of the pod.

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-sleeper
  namespace: default
spec:
  containers:
  - command:
    - sleep
    - "4800"
    image: ubuntu
    name: ubuntu-sleeper
    securityContext:
      capabilities:
        add: ["SYS_TIME"]

securityContext 를 추가한다. 

 

 

6.

Now update the pod to also make use of the NET_ADMIN capability.

Note: Only make the necessary changes. Do not modify the name of the pod.

apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-sleeper
  namespace: default
spec:
  containers:
  - command:
    - sleep
    - "4800"
    image: ubuntu
    name: ubuntu-sleeper
    securityContext:
      capabilities:
        add: ["SYS_TIME", "NET_ADMIN"]

net_admin 추가

 

파드 실행 중이니까 바로 수정안된다. 

파드 제거하고 수정된 경로에서 kubectl apply -f [파일명]

 


174. Network Policy

Traffic

웹서버, 백엔드 서버, db 서버 이렇게 있다.

Ingress & Egress

Ingress - 들어오는 거

Egress - 나가는 거

Network Security

노드와 파드들은 각자 ip 를 가지고 있다. 

파드들은 서로 통신 가능해야한다.

쿠버네티스는 기본적으로 파드들끼리 allow 정책을 한다. 

쿠버네티스를 예시로 들어보자. 모두 파드로 치환됨.

파드니까 모두 서로 통신 가능하다. 

네트워크 정책을 적용해서 트래픽을 통제하자

레이블을 지정한 후 적용한다.

Network Policy - Rules 

ingress 정책 

특정 포트, 파드로 통신마 허용함

Network Policy - yaml 구성

파드 셀렉터 먼저 오고 정책 타입이 들어간다. 

인그레스 관련해서 모두 영향 받음

당연히 create 명령
네트워크 정책에 영향 받는 것과 아닌 것 확인


175. Developing Network Policy

 

예로 들어보자

web 으로부터 db 접근을 막아야한다. 

db와 api 먼저 확인하자
db 입장에서 api 로부터 들어오는 ingress 만 잘관리하면 된다.

요청 받은 후 응답을 자동으로 해야하기 때문에 egress는 필요없다. 

yaml 파일 예시
네임스페이스가 필요한 경우 name 밑에 기입하자

 

특정 ns가 필요하면 matchLabels 밑에 명시

이 상황에서 podSelector 가 없다면 ?

Staging에서 들어오는 모든 트래픽이 허용된다. 

다시 api pod 로 변경

외부 백업 서버와 연결하고 싶다면 ?

ipBlock 을 추가한다. 

from 아래에선 독립적으로 조건이 적용된다.

Egress 추가하기 


176. Practice Test - Network Policy

1. How many network policies do you see in the environment?

 

We have deployed few web applications, services and network policies. Inspect the environment.

1개

 

2. What is the name of the Network Policy?

payroll-policy

 

3. Which pod is the Network Policy applied on?

payroll

 

 

4. What type of traffic is this Network Policy configured to handle?

 

ingress 만 

 

5.  What is the impact of the rule configured on this Network Policy?

internal 

 

6. What is the impact of the rule configured on this Network Policy?

internal pod can access port 8080 on payroll pod

 

7. Access the UI of these applications using the link given above the terminal.

 

8. Perform a connectivity test using the User Interface in these Applications to access the payroll-service at port 8080.

9. Perform a connectivity test using the User Interface of the Internal Application to access the external-service at port 8080.

 

10.

Create a network policy to allow traffic from the Internal application only to the payroll-service and db-service.

Use the spec given below. You might want to enable ingress traffic to the pod to test your rules in the UI.

Policy Name: internal-policy
Policy Type: Egress
Egress Allow: payroll
Payroll Port: 8080
Egress Allow: mysql
MySQL Port: 3306
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Egress
  - Ingress
  ingress:
    - {}
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: mysql
    ports:
    - protocol: TCP
      port: 3306

  - to:
    - podSelector:
        matchLabels:
          name: payroll
    ports:
    - protocol: TCP
      port: 8080

  - ports:
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP

 


휴 드디어 그 많은 분량의  section7 security 가 끝났다.

cka 너무 멀고 먼 길이여

화이팅

 

 

https://youtu.be/IJf5ioT2Iuw?list=PLApuRlvrZKogb78kKq1wRvrjg1VMwYrvi 

 


Docker 를 설치하자! 

 

Docker 설치하기 

둘다 켜자 

 

1. vb 에서 ubnutu, centos 둘다 부팅

2. xshell 에서 둘다 접속

 

Docker Docs: How to build, share, and run applications | Docker Documentation

 

 

Docker Docs: How to build, share, and run applications

 

docs.docker.com

 

download and install

당연히 리눅스로 간다.

우분투랑 데비안 동일함

우분투 먼저 

 

 

 

 

 

 

Install Docker Engine on Ubuntu | Docker Documentation

 

Install Docker Engine on Ubuntu

 

docs.docker.com

 

설치 방법은

외부 네트워크를 이용

1. repository 사용 (이걸로 실습해보자) 

- 요구 패키지 설치

- 인증서 저장

- url 등록

- 인스톨 

2. download 후 직접 설치 - usb에 담아서 설치

3. script를 이용한 설치 

 

 


 

우분투 도커 설치

1. 패키지 설치 

sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

 

 

2. 인증서 설치 Add Docker’s official GPG key:

sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

 

3. URL 등록

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

 

4. docker engine 설치

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

ce 데몬

cli 

containerd.io 도커 엔진이다.

sudo docker run hello-world

확인

 

도커엔진 설치 완료

sudo docker version 

서버, 클라이언트 두개 버전이 나온다. 

 

 

센트os 도커 설치

Install Docker Engine on CentOS | Docker Documentation

 

Install Docker Engine on CentOS

 

docs.docker.com

 

centos 는 따로 키를 설치안해도 된다. ( 자동으로 받아짐)

먼저 root 사용자로 변경

 

uninstall

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

 

1.  Set up the repository

sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

 

2. Install Docker Engine

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

 

 

3. service daemon 실행하기 

sudo systemctl start docker

sudo docker run hello-world

docker 확인 ! 

 


docker 관리자 권한 추가

 

guru 로 docker 접근하면 permission denied 가 뜬다.

root 권한으로 guru 에게 권한을 줘야한다 .

 

su - 

 

usermod -a -G docker guru

guru 계정에서 docker 실행된다 .

centos도 똑같이 실행

다시 부팅후에도 docker 가 자동 실행되도록 enable 하기 (우분투는 안해도됨) 

 

+ Recent posts