## /etc/mysql/my.cnf 설정 파일

# base directory

# Charset

# Logging

# General logging has huge performance penalty therefore is disabled by default


# Networking

# When a client connects, the server will perform hostname resolution,
# and when DNS is slow, establishing the connection will become slow as well.
# It is therefore recommended to start the server with skip-name-resolve to
# disable all DNS lookups. The only limitation is that the GRANT statements
# must then use IP addresses only.

# Tuning
join_buffer_size = 192K
tmp_table_size = 16M
max_heap_table_size = 16M

## Generally, it is unwise to set the query cache to be larger than 64-128M
## as the costs associated with maintaining the cache outweigh the performance
## gains.
## The query cache is a well known bottleneck that can be seen even when
## concurrency is moderate. The best option is to disable it from day 1
## by setting query_cache_size=0 (now the default on MySQL 5.6)
## and to use other ways to speed up read queries: good indexing, adding
## replicas to spread the read load or using an external cache.


# InnoDB
# The buffer pool is where data and indexes are cached: having it as large as possible
# will ensure you use memory and not disks for most read operations.
# Typical values are 50..75% of available RAM.
# TODO(tomasz.paszkowski): This needs to by dynamic based on available RAM.

# Clustering
wsrep_provider_options="gcache.size=512M; gcache.name=/tmp/galera.cache; gcache.page_size=128M; gmcast.listen_addr=tcp://"



## sync 상태 보기 (각 mariadb 서버에서)
MariaDB [(none)]> show status like 'wsrep_%';
| Variable_name                | Value                                                       |
| wsrep_apply_oooe             | 0.007694                                                    |
| wsrep_apply_oool             | 0.000000                                                    |
| wsrep_apply_window           | 1.014445                                                    |
| wsrep_causal_reads           | 0                                                           |
| wsrep_cert_deps_distance     | 25.653383                                                   |
| wsrep_cert_index_size        | 67                                                          |
| wsrep_cert_interval          | 0.007814                                                    |
| wsrep_cluster_conf_id        | 3                                                           |
| wsrep_cluster_size           | 3                                                           |
| wsrep_cluster_state_uuid     | 86cf6166-d00b-11e7-92f6-bf254b8a19b3                        |
| wsrep_cluster_status         | Primary                                                     |
| wsrep_commit_oooe            | 0.000000                                                    |
| wsrep_commit_oool            | 0.000000                                                    |
| wsrep_commit_window          | 1.006594                                                    |
| wsrep_connected              | ON                                                          |
| wsrep_desync_count           | 0                                                           |
| wsrep_evs_delayed            |                                                             |
| wsrep_evs_evict_list         |                                                             |
| wsrep_evs_repl_latency       | 0.000495221/0.000788639/0.00164732/0.00034555/19            |
| wsrep_evs_state              | OPERATIONAL                                                 |
| wsrep_flow_control_paused    | 0.000000                                                    |
| wsrep_flow_control_paused_ns | 0                                                           |
| wsrep_flow_control_recv      | 0                                                           |
| wsrep_flow_control_sent      | 0                                                           |
| wsrep_gcomm_uuid             | f14761b1-d026-11e7-a9c6-43e9a12bd841                        |
| wsrep_incoming_addresses     |,, |
| wsrep_last_committed         | 12525                                                       |
| wsrep_local_bf_aborts        | 0                                                           |
| wsrep_local_cached_downto    | 6127                                                        |
| wsrep_local_cert_failures    | 0                                                           |
| wsrep_local_commits          | 970                                                         |
| wsrep_local_index            | 2                                                           |
| wsrep_local_recv_queue       | 0                                                           |
| wsrep_local_recv_queue_avg   | 0.143574                                                    |
| wsrep_local_recv_queue_max   | 40                                                          |
| wsrep_local_recv_queue_min   | 0                                                           |
| wsrep_local_replays          | 0                                                           |
| wsrep_local_send_queue       | 0                                                           |
| wsrep_local_send_queue_avg   | 0.000978                                                    |
| wsrep_local_send_queue_max   | 2                                                           |
| wsrep_local_send_queue_min   | 0                                                           |
| wsrep_local_state            | 4                                                           |
| wsrep_local_state_comment    | Synced                                                      |
| wsrep_local_state_uuid       | 86cf6166-d00b-11e7-92f6-bf254b8a19b3                        |
| wsrep_protocol_version       | 7                                                           |
| wsrep_provider_name          | Galera                                                      |
| wsrep_provider_vendor        | Codership Oy <info@codership.com>                           |
| wsrep_provider_version       | 25.3.20(r3703)                                              |
| wsrep_ready                  | ON                                                          |
| wsrep_received               | 5579                                                        |
| wsrep_received_bytes         | 4241688                                                     |
| wsrep_repl_data_bytes        | 441822                                                      |
| wsrep_repl_keys              | 4283                                                        |
| wsrep_repl_keys_bytes        | 56574                                                       |
| wsrep_repl_other_bytes       | 0                                                           |
| wsrep_replicated             | 970                                                         |
| wsrep_replicated_bytes       | 560476                                                      |
| wsrep_thread_count           | 13                                                          |


wsrep_cluster_conf_id : 모든 db 에 똑같은 id 로 설정되어야 함

wsrep_cluster_size : 클러스터의 노드 갯수

wsrep_cluster_state_uuid : 고유 클러스터 ID 로 클러스터의 노드는 같은 값을 가져야 함

wsrep_cluster_status : 노드의 역할

wsrep_incoming_addresses : 클러스터 멤버의 ip 

wsrep_local_state_comment : 해당 노드가 클러스터의 멤버인지를 확인

wsrep_ready : 노드가 준비된 상태

## docker 내에서 클러스터 시작 (첫번째 클러스터)

$ sed -i 's/^safe_to_bootstrap:.*/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat || :

$ docker-entrypoint.sh mysqld --wsrep-new-cluster

## docker 내에서 클러스터 시작 (두번째, 세번째 클러스터)

$ sed -i 's/^safe_to_bootstrap:.*/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat || :

$ docker-entrypoint.sh mysqld

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com



안녕하세요. 코드의 시인, 조이입니다. 저는 보이지 않는 힘이 일어나는 것을 막기 위한 사명을 띠고 있어요. 제가 '코드화된 시선'이라 부르는 힘인데요. 다른 사람은 알고리즘의 편견이라 부르죠.

Hello, I'm Joy, a poet of code, on a mission to stop an unseen force that's rising, a force that I called "the coded gaze," my term for algorithmic bias.


알고리즘의 편견은 인간의 편견처럼 불평등을 초래하지만 알고리즘은 바이러스처럼 대규모의 편견을 빠른 속도로 퍼뜨릴 수 있어요. 또한, 알고리즘의 편견은 자신이 배제되는 경험이나 차별적인 대우로 이어질 수 있어요. 자세히 설명해 드리죠.

Algorithmic bias, like human bias, results in unfairness. However, algorithms, like viruses, can spread bias on a massive scale at a rapid pace. Algorithmic bias can also lead to exclusionary experiences and discriminatory practices. Let me show you what I mean.


(비디오) 안녕, 카메라야. 이게 내 얼굴이야. 내 얼굴이 보이니? 안경을 벗으면 보이니? 이 친구의 얼굴은 보이잖아. 내 얼굴은 보여? 그럼 가면을 쓸게. 내 가면이 보이니?

(Video) Hi, camera. I've got a face. Can you see my face? No-glasses face? You can see her face. What about my face? I've got a mask. Can you see my mask?


이런 일이 왜 일어난 걸까요? 제가 왜 컴퓨터 앞에 앉아서 하얀 가면을 쓰고 싸구려 웹캠에 인식이 되도록 노력하고 있을까요? 제가 코드의 시인으로서 '코드화된 시선'과 싸우기 전에 저는 MIT 미디어랩의 대학원생이었어요. 그곳에서 많은 기발한 프로젝트에 참여할 수 있었는데 염원의 거울도 있었습니다. 제가 참여한 프로젝트로, 거울에 비친 제 모습에 디지털 가면을 씌우는 프로젝트였죠. 아침에 힘찬 느낌을 원하면 사자 가면을 씌울 수 있고 희망찬 느낌을 받고 싶다면 명언을 띄울 수 있었죠. 저는 일반적인 얼굴 인식 소프트웨어를 사용하여 시스템을 만들었지만 제가 흰 가면을 쓰지 않으면 굉장히 테스트하기 어려웠어요.

So how did this happen? Why am I sitting in front of a computer in a white mask, trying to be detected by a cheap webcam? Well, when I'm not fighting the coded gaze as a poet of code, I'm a graduate student at the MIT Media Lab, and there I have the opportunity to work on all sorts of whimsical projects, including the Aspire Mirror, a project I did so I could project digital masks onto my reflection. So in the morning, if I wanted to feel powerful, I could put on a lion. If I wanted to be uplifted, I might have a quote. So I used generic facial recognition software to build the system, but found it was really hard to test it unless I wore a white mask.


불행하게도, 저는 전에도 이런 문제에 부딪힌 적이 있어요. 제가 조지아 공대에서 컴퓨터 공학 전공생이었을 때 저는 사회적 로봇을 연구했어요. 과제들 중 하나는 까꿍놀이하는 로봇을 만들기였죠. 간단한 순서 교대 게임으로, 얼굴을 가렸다가 보이며 "까꿍!"이라고 말하는 게임이죠. 문제는, 까꿍 놀이는 제가 여러분의 얼굴을 볼 수 있어야 하는데 로봇이 저를 보지 못했어요. 하지만 저는 룸메이트의 얼굴을 빌려서 프로젝트를 끝냈고 과제를 제출한 다음 다른 누군가가 이 문제를 해결하겠지 라고 생각했어요.

Unfortunately, I've run into this issue before. When I was an undergraduate at Georgia Tech studying computer science, I used to work on social robots, and one of my tasks was to get a robot to play peek-a-boo, a simple turn-taking game where partners cover their face and then uncover it saying, "Peek-a-boo!" The problem is, peek-a-boo doesn't really work if I can't see you, and my robot couldn't see me. But I borrowed my roommate's face to get the project done, submitted the assignment, and figured, you know what, somebody else will solve this problem.


그로부터 오래 지나지 않아 창업 대회 참가를 위해 홍콩에 갔어요. 주최 측은 참여자들이 그 지역의 스타트업 기업들을 방문하도록 했어요. 한 스타트업에 사회적 로봇이 있었고 시범을 보여주기로 했어요. 로봇은 모두에게 잘 작동했죠. 저만 빼고요. 아마 짐작하셨을 거예요. 제 얼굴을 인식하지 못했어요. 저는 개발자들에게 무슨 일이냐고 물었고 제가 썼던 그 얼굴 인식 소프트웨어를 쓴 게 문제였어요. 지구 반대편에서 저는 알고리즘의 편견이 인터넷에서 파일을 다운로드받는 것처럼 빠르게 퍼질 수 있다는 걸 알았어요.

Not too long after, I was in Hong Kong for an entrepreneurship competition. The organizers decided to take participants on a tour of local start-ups. One of the start-ups had a social robot, and they decided to do a demo. The demo worked on everybody until it got to me, and you can probably guess it. It couldn't detect my face. I asked the developers what was going on, and it turned out we had used the same generic facial recognition software. Halfway around the world, I learned that algorithmic bias can travel as quickly as it takes to download some files off of the internet.


어떻게 된 걸까요? 왜 제 얼굴은 인식되지 않죠? 자, 우리가 어떻게 기계가 볼 수 있게 하는지 알아보세요. 컴퓨터의 시야는 머신 러닝 기술을 사용해 얼굴을 인식해요. 우리는 여러 예시 얼굴들로 이루어진 연습 세트를 만들어 놓죠. 이건 얼굴이다. 이건 얼굴이다. 이건 얼굴이 아니다. 그리고 시간이 지나면, 컴퓨터에게 얼굴 인식을 가르칠 수 있어요. 하지만, 연습 세트가 그렇게 다양하지 않다면 규정된 표준에서 너무 벗어나는 얼굴들은 인식하기 어려울 거예요. 저한테 일어났던 일과 같죠.

So what's going on? Why isn't my face being detected? Well, we have to look at how we give machines sight. Computer vision uses machine learning techniques to do facial recognition. So how this works is, you create a training set with examples of faces. This is a face. This is a face. This is not a face. And over time, you can teach a computer how to recognize other faces. However, if the training sets aren't really that diverse, any face that deviates too much from the established norm will be harder to detect, which is what was happening to me.


하지만 걱정하지 마세요. 좋은 소식도 있어요. 연습 세트는 하늘에서 뚝 떨어지지 않아요. 우리가 직접 만들 수 있죠. 따라서 전 영역을 아울러 다양한 인류의 얼굴을 반영하는 연습 세트를 만들 기회가 있어요.

But don't worry -- there's some good news. Training sets don't just materialize out of nowhere. We actually can create them. So there's an opportunity to create full-spectrum training sets that reflect a richer portrait of humanity.


여러분은 방금 사회적 로봇이 어떤지 제가 어떻게 알고리즘의 편견에 의한 배제에 대해 알게되었는지 보셨어요. 하지만 알고리즘의 편견은 차별적 관행으로 이어질 수도 있습니다. 미국 전역에서 경찰서들이 범죄 근절의 무기로 얼굴 인식 소프트웨어를 사용하기 시작했어요. 조지타운대 법학센터에 따르면 총 1억1천7백만명에 달하는 미국 성인 둘 중 한 명의 얼굴이 얼굴 인식 네트워크에 올려져 있어요. 경찰은 현재 이 네트워크를 제한 없이 살펴볼 수 있어요. 정확성이 검증되지 않은 알고리즘을 사용하면서요. 우리는 얼굴 인식이 잘못될 수 있다는 것을 알고 있고 얼굴을 일관되게 표시하는 것은 과제로 남아있어요. 아마 페이스북에서 보셨을 거예요. 저와 제 친구들은 다른 사람의 이름이 우리 사진에 표시된 것을 보고 매번 웃어요. 하지만 범죄 용의자를 잘못 파악하는 것은 웃을 일이 아니며 시민의 자유를 침해하죠.

Now you've seen in my examples how social robots was how I found out about exclusion with algorithmic bias. But algorithmic bias can also lead to discriminatory practices. Across the US, police departments are starting to use facial recognition software in their crime-fighting arsenal. Georgetown Law published a report showing that one in two adults in the US -- that's 117 million people -- have their faces in facial recognition networks. Police departments can currently look at these networks unregulated, using algorithms that have not been audited for accuracy. Yet we know facial recognition is not fail proof, and labeling faces consistently remains a challenge. You might have seen this on Facebook. My friends and I laugh all the time when we see other people mislabeled in our photos. But misidentifying a suspected criminal is no laughing matter, nor is breaching civil liberties.


머신러닝은 현재 얼굴인식에 사용되지만 컴퓨터 시각을 넘어선 곳까지 확장되고 있어요. '대량살상무기 (WMD)'라는 책에서 데이터 과학자 캐시 오닐은 새로운 대량살상무기에 대해서 말해요. 널리 퍼진, 알 수 없는 파괴적인 알고리즘이죠. 이들은 우리 삶에 큰 영향을 미치는 선택에 점점 많이 사용되고 있어요. 누가 고용되고 누가 해고되는가? 빚을 질까? 보험에 가입할까? 원하는 대학에 합격하는가? 여러분과 당신이 같은 상품에 대해서 같은 가격을 지불하는가?

Machine learning is being used for facial recognition, but it's also extending beyond the realm of computer vision. In her book, "Weapons of Math Destruction," data scientist Cathy O'Neil talks about the rising new WMDs -- widespread, mysterious and destructive algorithms that are increasingly being used to make decisions that impact more aspects of our lives. So who gets hired or fired? Do you get that loan? Do you get insurance? Are you admitted into the college you wanted to get into? Do you and I pay the same price for the same product purchased on the same platform?


법 집행에서도 예방적 치안을 위해 머신 러닝 사용을 시작했어요. 몇몇 판사들은 기계가 만든 위험 점수를 사용하여 사람들의 형량을 결정하기도 해요. 그래서 우린 이런 선택에 대해 생각해 봐야 해요. 이 선택이 공정한가? 게다가 우리는 알고리즘의 선택이 매번 공정하지는 않다는 걸 봤어요.

Law enforcement is also starting to use machine learning for predictive policing. Some judges use machine-generated risk scores to determine how long an individual is going to spend in prison. So we really have to think about these decisions. Are they fair? And we've seen that algorithmic bias doesn't necessarily always lead to fair outcomes.


그럼 어떻게 해야 할까요? 우리는 포괄적인 코드를 만들고 포괄적인 코딩 선례를 도입해야 해요. 이것은 사람들로부터 시작됩니다. 따라서, 누가 코딩을 하는지가 중요하죠. 우리는 지금 다양한 개인들로 이루어져 서로의 맹점을 볼 수 있는 팀을 만들고 있나요? 기술적인 면에서 우리가 어떻게 코딩을 하는지가 중요해요. 지금 우리는 시스템을 개발하면서 공정함을 염두에 두고 있나요? 마지막으로, 우리가 왜 코딩을 하는지가 중요해요. 우리는 엄청난 부를 위하여 컴퓨터를 도구로 사용했어요. 이제 우리에겐 더 큰 평등을 얻을 기회가 있어요. 우리가 사회적 변화를 미루지 않고 우선순위에 둔다면요. 이 세 가지 요소가 '인코딩' 운동을 구성합니다. 누가 코딩을 하는지 어떻게 코딩을 하는지 왜 코딩을 하는지가 중요해요.

So what can we do about it? Well, we can start thinking about how we create more inclusive code and employ inclusive coding practices. It really starts with people. So who codes matters. Are we creating full-spectrum teams with diverse individuals who can check each other's blind spots? On the technical side, how we code matters. Are we factoring in fairness as we're developing systems? And finally, why we code matters. We've used tools of computational creation to unlock immense wealth. We now have the opportunity to unlock even greater equality if we make social change a priority and not an afterthought. And so these are the three tenets that will make up the "incoding" movement. Who codes matters, how we code matters and why we code matters.


그리고 인코딩을 향해 가며 우리는 편견을 분별하는 플랫폼을 구축할 수 있어요. 제가 공유한 것과 같은 다른 사람들의 경험을 모으고 현존하는 소프트웨어를 검사하면서 말이죠. 우리는 또한 더욱 포용적인 연습 세트를 만들기 시작할 수 있어요. "포괄적인 셀카" 캠페인을 상상해 보세요. 여러분과 제가 더욱 포용적인 연습 세트를 만드는 데 셀카를 보내면서 도움을 줄 수 있는 거예요. 그리고 우리가 개발하는 기술의 사회적 영향에 대해 보다 양심적으로 생각할 수 있어요.

So to go towards incoding, we can start thinking about building platforms that can identify bias by collecting people's experiences like the ones I shared, but also auditing existing software. We can also start to create more inclusive training sets. Imagine a "Selfies for Inclusion" campaign where you and I can help developers test and create more inclusive training sets. And we can also start thinking more conscientiously about the social impact of the technology that we're developing.


인코딩 운동을 시작하기 위해서 저는 알고리즘 정의 연합을 창설했어요. 공정함을 중요시 여기는 사람 누구든 '코딩된 시선'에 맞서 싸우는 걸 도와줍니다. codedgaze.com에서 편견을 보고하거나 검사를 요청하거나 테스터가 될 수 있으며 진행되는 대화에 참여할 수도 있어요. 해시태그 codedgaze입니다.

To get the incoding movement started, I've launched the Algorithmic Justice League, where anyone who cares about fairness can help fight the coded gaze. On codedgaze.com, you can report bias, request audits, become a tester and join the ongoing conversation, #codedgaze.


그래서 저는 여러분이 저와 함께 기술이 일부만이 아닌 모두를 위해 쓰이는 세상을 포용성을 중요시여기고 사회적 변화를 중시하는 세상을 만드는데 동참하셨으면 합니다.

So I invite you to join me in creating a world where technology works for all of us, not just some of us, a world where we value inclusion and center social change.



Thank you.





하지만 여러분에게 질문이 하나 있어요. 여러분은 이 싸움에 동참하실 건가요?

But I have one question: Will you join me in the fight?







저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

[ dynamic volume 사용법 ]
1. pvc 에 storageclass 를 지정하여 pvc 만 생성하면 pv 가 다이너믹하게 생성되고 pvc 도 생성된다.
2. 이 때 rbd 이미지도 자동으로 생성된다.

$ vi jenkins-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
  name: jenkins
  namespace: ci-infra
  - ReadWriteMany
      storage: 100Gi
  storageClassName: ceph

[ static volume 사용법 ]
1. rbd 이미지를 수동으로 생성해야 한다.
2. pv 에 storageclass 와 rbd 값을 모두 넣어야 한다.
    pv 에 pvc 에서 pv 를 selector 로 찾을 수 있게 label 값을 넣어야 한다.
    (keyring 값은 안넣어도 됨, storageclass의 secret 이용)
3. pvc 에 storageclass 와 selector 나 volumeName 둘 중에 하나를 사용하여 pv 와 연결한다.
    (storageclass 는 값은 없어도 됨.  없으면 default 인 storageclass 값을 활용함)

$ vi jenkins-pv.yaml
apiVersion: v1
kind: PersistentVolume
  name: jenkins
    app: jenkins
    storage: 100Gi
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ceph
    image: jenkins
    pool: kubes
      name: ceph-secret-user
    user: kube

$ vi jenkins-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
  name: jenkins
  namespace: ci-infra
  - ReadWriteMany
      storage: 100Gi
  storageClassName: ceph
      app: jenkins
# volumeName: jenkins

$ vi jenkins-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
  name: jenkins
  namespace: ci-infra
    app: jenkins
  replicas: 1
    type: Recreate
        app: jenkins
            - matchExpressions:
              - key: cicd-services
                operator: In
                - enabled
        runAsUser: 1000
        fsGroup: 1000
      - name: master
        - name: JENKINS_OPTS
          value: "--httpsPort=0 --http2Port=0"
        - name: JAVA_OPTS
          value: "-Xms8G -Xmx8G -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:+UnlockDiagnosticVMOptions -XX:G1SummarizeRSetStatsPeriod=1 -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Seoul"
        image: jenkins/jenkins:latest
        imagePullPolicy: Always
        - containerPort: 8080
          name: http
          protocol: TCP
        - containerPort: 50000
          name: jnlp
          protocol: TCP
            path: /login
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 2
          failureThreshold: 5
        - mountPath: /var/jenkins_home
          name: jenkins
#        resources:
#          limits:
#            cpu: 4000m
#            memory: 8000Mi
#          requests:
#            cpu: 1000m
#            memory: 8000Mi
      - name: jenkins
          claimName: jenkins

## 생성
$ rbd create kubes/jenkins -s 100G
$ kubectl create -f jenkins-pv.yaml
$ kubectl create -f jenkins-pvc.yaml

$ kubectl create -f jenkins-deployment.yaml 

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

## Install OpenVPN

# apt-get update
# apt-get install openvpn easy-rsa

## Set Up the CA Directory (using easy-rsa)
# make-cadir /etc/openvpn/ease-rsa
# cd /etc/openvpn/ease-rsa

## Configure the CA Variables
# vi vars
export KEY_PROVINCE="Seoul"
export KEY_CITY="Jongno"
export KEY_ORG="OpenStackKR"
export KEY_EMAIL="root@localhost"
export KEY_OU="OpenStack KR"
export KEY_NAME="server"

## Build the Certificate Authority
# source vars
# ./clean-all
# ./build-ca
Generating a 2048 bit RSA private key
writing new private key to 'ca.key'
Country Name (2 letter code) [KR]:
State or Province Name (full name) [Seoul]:
Locality Name (eg, city) [Jongno]:
Organization Name (eg, company) [OpenStackKR]:
Organizational Unit Name (eg, section) [OpenStackKR]:
Common Name (eg, your name or your server's hostname) [OpenStackKR CA]:
Name [server]:
Email Address [root@localhost]:

## Create the Server Certificate, Key, and Encryption Files
# ./build-key-server server

A challenge password []:               --> 그냥 엔터
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

# ./build-dh
# openvpn --genkey --secret keys/ta.key

## Generate a Client Certificate and Key Pair
# cd /etc/openvpn/ease-rsa
# source vars
./build-key seungkyua
Generating a 2048 bit RSA private key
writing new private key to 'seungkyua.key'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [KR]:
State or Province Name (full name) [Seoul]:
Locality Name (eg, city) [Jongno]:
Organization Name (eg, company) [OpenStackKR]:
Organizational Unit Name (eg, section) [OpenStackKR]:
Common Name (eg, your name or your server's hostname) [seungkyua]:
Name [server]:
Email Address [root@localhost]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:password
An optional company name []: OpenStackKR
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'KR'
stateOrProvinceName   :PRINTABLE:'Seoul'
localityName          :PRINTABLE:'Jongno'
organizationName      :PRINTABLE:'OpenStackKR'
commonName            :PRINTABLE:'seungkyua'
name                  :PRINTABLE:'server'
emailAddress          :IA5STRING:'root@localhost'
Certificate is to be certified until Aug 29 01:42:22 2027 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

## Configure the OpenVPN Service
# cd /etc/openvpn/ease-rsa/keys
# cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn
# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf

# vi /etc/openvpn/server.conf
32 port 1194
35 proto tcp
78 ca ca.crt
79 cert server.crt
80 key server.key

141 push "route"
142 push "route"
143 push "route"
144 push "route"
145 push "route"
146 push "route"

205 push "dhcp-option DNS"    # 사설 DNS 서버가 설치될 서버 IP
206 push "dhcp-option DNS"
208 push "dhcp-option DOMAIN cicd.seungkyua"   # 사설 DNS 도메인

250 tls-auth ta.key 0
256 cipher AES-128-CBC   # AES
259 auth SHA256
275 user nobody
276 group nogroup

## Adjust the Server Networking Configuration
# vi /etc/sysctl.conf
28 net.ipv4.ip_forward=1

# sysctl -p

# ip route | grep default
# iptables -t nat -A POSTROUTING -s -o br-ex -j MASQUERADE

## Start and Enable the OpenVPN Service
# systemctl start openvpn@server
# systemctl status openvpn@server
# systemctl enable openvpn@server

## Create Client Configuration Infrastructure
# cd /etc/openvpn
# mkdir -p /etc/openvpn/client-configs/files
# chmod 700 /etc/openvpn/client-configs/files
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client-configs/base.conf

# vi client-configs/base.conf
36 proto tcp
42 remote server_ip 1194
61 user nobody
62 group nogroup
88 #ca ca.crt
89 #cert client.crt
90 #key client.key
113 cipher AES-128-CBC
114 auth SHA256
115 key-direction 1

# vi client-configs/make_config.sh

# First argument: Client identifier


cat ${BASE_CONFIG} \
    <(echo -e '<ca>') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '</ca>\n<cert>') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '</cert>\n<key>') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '</key>\n<tls-auth>') \
    ${KEY_DIR}/ta.key \
    <(echo -e '</tls-auth>') \
    > ${OUTPUT_DIR}/${1}.ovpn

# chmod 700 client-configs/make_config.sh

# cd /etc/openvpn/client-configs

## seungkyua.ovpn 파일이 /etc/openvpn/client-configs/files 디렉토리 밑에 생성됨
# ./make_config.sh seungkyua

## 사용자 추가 시 클라이언트 파일 만드는 법

# cd /etc/openvpn/ease-rsa
# source vars
# ./build-key seungkyua

# cd /etc/openvpn/client-configs
# ./make_config.sh seungkyua

## server reboot 시 체크
# ip route | grep default

# iptables -t nat -A POSTROUTING -s -o br-ex -j MASQUERADE

출처 : https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-16-04

## Install Bind on the DNS Server
# sudo apt-get update
# apt-get install unbound

## config 설정
# cd /etc/unbound
# vi unbound.conf.d/root-auto-trust-anchor-file.conf
    verbosity: 1
    statistics-interval: 0
    statistics-cumulative: no
    extended-statistics: yes
    num-threads: 2


    outgoing-range: 4096
    outgoing-port-permit: 40000-44096
    cache-max-ttl: 3600
    do-ip4: yes
    do-ip6: no

    access-control: allow
    access-control: allow
    access-control: allow

    chroot: ""
    username: "unbound"
    directory: "/etc/unbound"
    log-time-ascii: yes
    pidfile: "/var/run/unbound/unbound.pid"
    hide-identity: yes
    hide-version: yes
    harden-short-bufsize: yes
    harden-large-queries: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    harden-below-nxdomain: yes
    harden-referral-path: yes
    use-caps-for-id: yes
    unwanted-reply-threshold: 10000000
    prefetch: yes
    prefetch-key: yes
    rrset-roundrobin: yes
    minimal-responses: yes
#    trusted-keys-file: /etc/unbound/keys.d/*.key
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    val-clean-additional: yes
    val-permissive-mode: no
    val-log-level: 1
    key-cache-size: 512m

    include: /etc/unbound/local.d/*.conf

# Remote control config section.
    control-enable: yes
    server-key-file: "/etc/unbound/unbound_server.key"
    server-cert-file: "/etc/unbound/unbound_server.pem"
    control-key-file: "/etc/unbound/unbound_control.key"
    control-cert-file: "/etc/unbound/unbound_control.pem"

# Stub and Forward zones
# include: /etc/unbound/conf.d/*.conf

## dns 설정
# mkdir -p local.d
# vi local.d/cicd.seungkyua.conf
local-zone: "cicd.stg.taco." static
local-data: "master01.cicd.seungkyua. IN A"
local-data: "node01.cicd.seungkyua. IN A"
local-data: "node02.cicd.seungkyua. IN A"
local-data: "node03.cicd.seungkyua. IN A"
local-data: "node04.cicd.seungkyua. IN A"

local-data: "centos-repo.cicd.seungkyua. IN A"
local-data: "dashboard.cicd.seungkyua. IN A"
local-data: "grafana.cicd.seungkyua. IN A"
local-data: "horizon.cicd.seungkyua. IN A"
local-data: "jenkins.cicd.seungkyua. IN A"
local-data: "keystone.cicd.seungkyua. IN A"
local-data: "kibana.cicd.seungkyua. IN A"
local-data: "minio.seungkyua. IN A"
local-data: "pypi-repo.cicd.seungkyua. IN A"
local-data: "registry.cicd.seungkyua. IN A"
local-data: "scope.cicd.seungkyua. IN A"
local-data: "prometheus.cicd.seungkyua. IN A"
local-data: "ubuntu-repo.cicd.seungkyua. IN A"

## start unbound
# systemctl restart unbound.service

# systemctl enable unbound.service 

출처 : https://calomel.org/unbound_dns.html

## reload unbound server with new configuration

# unbound-control reload

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

Youtube 동영상

영문 스트립트

지금부터 나와 주변 사람들에게 물어야 할 인생의 다섯 가지 중요한 질문을 소개합니다.

My final suggestion is that there are five truly essential questions that you should regularly ask yourself and others.

거창할지 모르지만 이해해주길 바랍니다. 졸업 축사이니까.

My claim is that, this is slightly outlandish as a claim but this is a graduation speech.

이 질문을 하는 습관을 들이면 성공적이고 행복한 삶을 살며 마지막의 보너스 질문에 '네'라고 자신 있게 답할 수 있습니다.

if you get in the habit of asking these questions, you have a very good chance of being both successful and happy,

and you will be in a good position to answer “I did” to the bonus question at the end.

1.잠깐만요, 뭐라고요? (Wait, What?)

첫 번째 질문은 우리 아이가 좋아하는 질문이자 십대들이 특히 자주 하고 우리들도 곧잘 하는 질문입니다.

The first is a question my own kids are fond of asking, and it’s one you may have heard other teenagers pose — or maybe you still pose it yourself.

질문이 고전적입니다. '잠깐만요, 뭐라고요?'

The question is the classic, 'Wait, what?'

'잠깐만, 뭐라고?' 또는 '잠깐만요, 뭐?'라고 하기도 합니다.

It could be asked is 'Wait, What?' or 'Wait, What?' (둘의 억양이 다름)

우리 아이들은 보통 내가 집안일을 시키려 할 때 이 질문을 합니다.

My kids typically pose this question when I get to the point in a conversation where I’m asking them to do a chore or two.

아이들 입장에선 내 말이 이렇게 들립니다. "어쩌구... 저쩌구... 내일 아침에 방 좀 치워라!"

From their perspective, they hear me saying something like: "blah, blah, blah, blah, and then I’d like you to clean your room."

바로 그 순간에 아이들은 묻습니다. "잠깐만요, 뭐라고요, 뭘 치우라고요?"

And at that precise moment, the question inevitably comes: "Wait, what? Clean what?"

'잠깐만, 뭐라고?'는 사실 무언가를 명확히 하기위한 매우 효과적인 질문으로, 이해를 위해 필수적입니다.

"Wait what" is actually a very effective way of asking for clarification, which is crucial to understanding.

결론을 내리기 전과 결정을 하기 전에 물어야만 하는 질문입니다.

It’s the question you should ask before drawing conclusions or before making a decision.

하바드 학장인 라케시 쿠라나는 훌륭한 마스터클래스를 진행하며 지지에 앞서 질의의 중요성을 강조했습니다.

The Dean of Harvard College, Rakesh Khurana, gave a great master class this year, where he emphasized the importance of inquiry before advocacy.

어떤 의견을 반대하거나 지지하기 전에 상황과 개념을 이해하는 것이 중요합니다.

It’s important to understand an idea before you advocate for or against it.

'뭐라고요?' 전에 오는 '잠깐만요'는 진정으로 이해할 수 있도록 잠시 시간을 갖게 하는 좋은 알람입니다.

The wait, which precedes the what, is also a good reminder that it pays to slow down to make sure you truly understand.

2. 나는 궁금한데요? (I wonder...)

두 번째 질문은 '나는 궁금한데요?'입니다. 이 질문은 왜 그런지(wonder why)와 할 수 있는지(wonder if)가 이어집니다.

The second question is "I wonder" which can be followed by "why" or "if". So I wonder why, or I wonder if.

'왜 그런지'라는 질문은 이 세상에 호기심을 갖게 합니다. '할 수 있는지'라는 질문은 세상이 더 나아지도록 하는 방법을 생각하게 합니다.

Asking 'I wonder why' is the way to remain curious about the world, and asking 'I wonder if' is the way to start thinking about how you might improve the world.

다음과 같이, 나는 왜 미국의 학교가 인종적으로 분리되어 있는지 궁금했습니다. 우리가 이 상황을 바꿀 수 있을 지 궁금했습니다.

As in, I wonder why our schools are so segregated, and I wonder if we could change this?

나는 왜 학생들이 학교생활을 지루해 하는지 궁금했습니다. 학생들이 집중할 수 있는 수업을 만들 수 있는지 궁금했습니다.

Or I wonder why students often seem bored in school, and I wonder if we could make their classes more engaging?

3. 적어도... 할 수 있지 않을까? (Couldn't we at least?)

세 번째 질문은 '적어도... 할 수 있지 않을까요?'입니다.

The third question is: "Couldn’t we at least...?"

이 질문은 보통 우리가 꽉 막힌 곳에서 빠져나올 때 유용합니다. 의견 차를 넘어 합의에 도달할 때 유용합니다.

This is the question to ask that will enable you to get unstuck, as they say. It’s what enables you to get past disagreement to some consensus,

다음과 같이, 우리가 주장하는 교육 전략은 다르다 해도 학생들의 복지가 최우선이라는 건 동의하지 않나요?

as in, couldn’t we at least agree that we all care about the welfare of students, even if we disagree about strategy?

또한 일의 결과를 확신하지 못하더라도 일단 무언가를 시작할 때 유용합니다.

It’s also a way to get started when you’re not entirely sure where you will finish,

다음과 같이, 적어도 모든 학생들이 잘 먹고 건강하게 학교에 다닐 수 있는 기회를 주는 것을 시작해야 하지 않나요?

as in, couldn’t we at least begin by making sure that all kids have the chance to come to school healthy and well-fed?

4. 내가 어떻게 도울까? (How can I help?)

내 번째 질문은 '내가 어떻게 도울까?'입니다.

The fourth question is: "How can I help?"

여러분은 누군가를 돕고 싶어 교육대학원에 들어왔을 겁니다.

You are at HGSE, I presume, because you are interested in helping others.

하지만 여기서 구원자 증후군, 당신이 누군가를 구원하는 전문가이고 영웅이라는 태도에 대해 인식하게 되었을 겁니다.

But you also know, from your time here, to be aware of the savior complex, of the stance where you are the expert or hero who swoops in to save others.

우리는 구원자 증후군 때문에 가장 인간적인 본능인 타인에게 손을 내미는 본능을 버려서는 안 됩니다.

We shouldn’t let the real pitfalls of the savior complex extinguish one of the most humane instincts there is — the instinct to lend a hand.

하지만 어떻게 돕느냐가 더 중요할 수 있습니다.

But how we help matters as much as that we do help,

"어떻게 도울까?"라고 묻는 것은 도움의 방향을 겸손하게 묻는 것이며,

and if you ask "how you can help", you are asking, with humility, for direction.

그들이 자기 삶의 전문가이자 당신이 돕는 만큼 그들도 당신을 도울 수 있다는 사실을 깨닫게 합니다.

And you are recognizing that others are experts in their own lives and that they will likely help you as much as you help them.

5. 무엇이 가장 중요한가? (What truly matters?)

다섯 번째 질문은 '무엇이 가장 중요한가?'입니다.

The fifth question is this: "What truly matters?"

여러분도 적절한 질문이라 생각할 것입니다.

You can tack on "to me" as appropriate.

이 질문은 문제의 핵심과 믿음과 신념의 핵심으로 들어가게 해주는 질문입니다.

This is the question that forces you to get to the heart of issues and to the heart of your own beliefs and convictions.

매년 새해 결심에 추가하거나 대신할 수도 있는 질문입니다.

Indeed, it’s a question that you might add to, or substitute for, New Year’s resolutions.

새해 첫날 내게 무엇이 진정 중요한가 물을 수 있습니다.

You might ask yourself, in other words, at least every new year: what truly matters to me?

이것이 다섯 개의 중요한 필수 질문입니다.

So these are the five essential questions.

'잠깐만요, 뭐라고요?'는 모든 이해의 근원입니다.

"Wait, what" is at the root of all understanding.

'궁금해'는 모든 호기심의 근원입니다.

"I wonder" is at the heart of all curiosity.

'우리가 적어도... 할 수 있지 않을까?'는 모든 진전의 시작입니다.

"Couldn’t we at least" is the beginning of all progress.

'어떻게 도울 수 있을까?'는 모든 좋은 관계의 기본입니다.

"How can I help" is at the base of all good relationships.

'무엇이 가장 중요한가?'는 삶의 핵심으로 들어가게 해줍니다.

And "what really matters" gets you to the heart of life.

이 질문을 정기적으로, 특히 마지막 질문을 자주 한다면 보너스 질문에 답할 좋은 위치에 서게 됩니다.

If you ask these questions regularly, especially the last one, you will be in a great position to answer the bonus question,

이것은 생의 마지막에서 여러분이 만나게 될 가장 중요한 질문입니다.

which is, at the end of the day, the most important question you’ll ever face.

이 보너스 질문은 여러 버전이 있으며, 이전에 한 버전은 확실히 들었을 것입니다.

This bonus question is posed in many ways, and you have surely heard a version of it before.

나에게 가장 강렬한 한 문장으로 다가온 것은 레이먼드 카버의 시 <만년의 조각글>에서 였습니다.

To me, the single best phrasing of this question is in a poem by Raymond Carver, called "Late Fragments".

그가 쓴 마지막 시입니다.

It’s one of the last poems he wrote.

지난 9월 나의 법대 동기이자 가장 사랑하는 친구였던 더그 켄들의 장례식에서 이 문장을 만났습니다.

I came across it recently on the very sad occasion of a memorial service for one of my dearest and closest friends, my former law school roommate Doug Kendall,

51세라는 너무 젊은 나이에 세상을 떠난 친구입니다.

who died in September at the far too young age of 51.

이 시는 그의 장례식 식순 뒤에 적혀 있었습니다. 시는 질문으로 시작하는데 이것이 바로 나의 보너스 질문에 해당합니다.

The poem was printed on the back of the program for his memorial and it starts with this question, what I’m calling the bonus question.

'그럼에도 불구하고 당신은 이 삶에서 원하는 것을 얻었습니까?'

"And did you get what you wanted out of life, even so?"

그럼에도 불구하고 이 부분이, 나에게는, 긴 인생과 삶의 희망에서 피할 수 없는 고통과 실망을 완벽하게 잡아냈다고 생각합니다.

The "even so" part of this, to me, captures perfectly the recognition of the pain and disappointment that inevitably make up a full life, but also the hope that life,

또한 '그럼에도 불구하고' 우리 인생에 행복과 만족의 가능성이 함께 함을 이야기합니다.

even so, offers the possibility of joy and contentment.

당신이 '잠깐만요, 뭐라고요?, 나는 궁금한데요?, 적어도 할 수 있지 않을까?, 어떻게 도울까?, 무엇이 가장 중요한가?' 이 질문을 주기적으로 한다면,

My claim is that if you regularly ask: wait, what, I wonder, couldn’t we at least, how can I help, and what really matters,

'마지막 그럼에도 불구하고 당신은 삶에서 원하는 것을 얻었는가?'라는 질문에 '네'라고 대답할 수 있을 것입니다.

when it comes time to ask yourself "And did you get what you wanted out of life, even so", your answer will be "I did".

이 시는 '그럼에도 불구하고 원하는 것을 얻었는가?'라는 질문에 '그렇다'라고,

So the poem asks "And did you get what you wanted out of life, even so",

또 "당신은 무엇을 원했습니까?"에 "이 지상에서, 나를 사랑받는 사람이라 부를 수 있고, 사랑받고 있다고 느끼는 것"이라고 답합니다.

and then continues: "I did. And what did you want?", "To call myself beloved. To feel beloved on the earth.".

사랑을 받는다는 건 지극히 사랑받는다는 것 뿐 아니라 소중히 여겨지고 존경받는 것입니다.

The word "beloved" is important here as it not only means dearly loved, but also cherished and respected.

이제 나의 축사가 거의 끝나가고 있으니 한 가지만 당부합니다.

And while I promise I’m very near the end of my speech, let me just say that

이 시를 읽으며 학생들을 생각할 수밖에 없었습니다.

when I read these lines, it’s hard for me not to think about students.

우리는 이곳은 물론 다른 곳에서 우리가 가르치는 학생들의 실력을 어떻게 향상시킬까를 항상 고민해야 합니다.

We spend a lot of time, here and elsewhere, thinking about how we might improve student performance, which is how it should be.

학생들이 공부를 잘할 뿐만 아니라 사랑받고 있다고 느낀다면 모든 학교와 이 세상은 보다 나은 곳이 될 것입니다.

Yet I can’t help but think that schools, and indeed, the world, would be better places if students didn’t simply perform well but also felt beloved

모든 학생들은 선생님께 사랑받고 친구들에게 사랑받아야 합니다.

- beloved by their teachers and by their fellow classmates.

이제 축사를 마무리하며 여러분에게 마지막 인사를 전합니다.

To tie this all together into one slightly misshapen package, and to bid you a final farewell.

이제 대학원을 떠나 여러분을 절실히 필요로 하는 넓은 세상에 나아갈 여러분에게 나의 소망과 신념을 꼭 전하고 싶습니다.

As you leave Appian Way and head into a world that desperately needs you, let me express my sincere hope and belief that

좋은 질문을 하고, 듣기를 멈추지 않는다면 여러분 자신이 이 지상에서 사랑받고 있다고 느낄 것이며,

if you never stop asking and listening for good questions, you will feel beloved on this earth,

마찬가지로, 다른 사람들 특히 여러분의 학생들이 사랑받는다고 느끼게 해줄 수 있습니다.

and, just as importantly, you will help others, especially students, feel the same.


Thank you very much.

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

OpenStack Day Korea 2017 에서 발표한 자료

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

## OpenStack Foundation 사용자 등록

## launchpad 에 사용자 등록 (OpenStack Foundation email 과 동일해야 함)

## launchpad.net 사용자 id 확인 (자신의 id 로 조회되는지 확인)

## review 사이트에 사용자 등록

## review 사이트에서 필요한 정보 등록
1. Profile 메뉴에서 Username 등록
2. Contact Information 에서 아래 처럼 날짜 업데이트 되었는지 확인 (안되어 있으면 정보 입력)
   Contact information last updated on May 25, 2015 at 12:51 PM.
3. SSH Public Keys 등록
   $ cat ~/.ssh/id_rsa.pub
4. Agreements 서명

[ stackalytics 에 추가 ]
$ mkdir -p ~/Documents/git && cd ~/Documents/git
$ git clone ssh://seungkyu@review.openstack.org:29418/openstack/stackalytics
$ cd stackalytics

## git 및 git-review 설치
$ brew install git git-review

## 환경 설정 (gitreview.username 은 review 사이트의 Profile Username 임)
$ git config --add gitreview.username "seungkyu"
git config --add user.name "Seungkyu Ahn"
git config --add user.email "seungkyua@gmail.com"

## 접속 테스트 및 commit-msg hook 다운로드
$ git review -s

## 개인 추가 (launchpad_id 의 abc 순), end_date: null 은 하나 밖에 못씀
## launchpad_id 만 필수, 나머지 id 는 옵션
$ git checkout -b seungkyua
$ vi etc/default_data.json
            "launchpad_id": "seungkyua",
            "gerrit_id": "seungkyu",
            "github_id": "seungkyua",
            "companies": [
                    "company_name": "Samsung SDS",
                    "end_date": "2015-Feb-28"
                    "company_name": "OpenStack Korea User Group",
                    "end_date": "2016-Dec-31"
                    "company_name": "SK telecom",
                    "end_date": null
            "user_name": "Seungkyu Ahn",
            "emails": ["ahnsk@sk.com", "seungkyua@gmail.com"]

## companies 항목에 회사명이 없을 때는 추가해야 함
25785         {
25786             "domains": ["sktelecom.com"],
25787             "company_name": "SK telecom",
25788             "aliases": ["SKT", "SKTelecom"]
25789         },

$ git commit -a

## commit message 는 아래와 같이
modify personal info about seungkyua

## commit message 작성법
첫번째 라인은 50자 이내로 간단히 요약을 쓴다.
설명을 적되 라인은 72자가 넘어가면 다음 라인에 쓴다.

## review 올리기
$ git review

## git review 시 Change-Id 세팅 에러가 나면 화면 에러 대로 수행
$ gitdir=$(git rev-parse --git-dir); scp -p -P 29418 seungkyu@review.openstack.org:hooks/commit-msg ${gitdir}/hooks/

$ git commit --amend
$ git review

## 확인

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com

ip link 로 device 를 namespace 로 보내면 Host 에서 해당 device 는 볼 수 가 없다.

이를 다시 Host 로 원복하는 방법

## Host 서버의 eno2 를 qrouter namespace 에 넣고 ip 세팅
$ sudo ip netns

## eno2 를 네임스페이스로 보내기
$ sudo ip link set eno2 netns qrouter-68cfc511-7e75-4b85-a1ca-d8a09c489ccc
$ sudo ip netns exec qrouter-68cfc511-7e75-4b85-a1ca-d8a09c489ccc ip a
4: eno2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 3c:a8:2a:20:ed:d1 brd ff:ff:ff:ff:ff:ff

$ sudo ip netns exec qrouter-68cfc511-7e75-4b85-a1ca-d8a09c489ccc ip addr add dev eno2
$ sudo ip netns exec qrouter-68cfc511-7e75-4b85-a1ca-d8a09c489ccc ifconfig eno2 up

## qrouter namespace 에 있는 eno2 를 Host 로 다시 돌려 보내기

$ ip netns exec qrouter-68cfc511-7e75-4b85-a1ca-d8a09c489ccc ip link set eno2 netns 1

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com
## https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/cephfs

[ ceph-admin 노드에서 ]
$ ssh ceph@

## kubes Pool 생성
$ ceph osd pool create kubes 128

## kube user 생성
$ ceph auth get-or-create client.kube mon 'allow r' \
osd 'allow class-read object_prefix rbd_children, allow rwx pool=kubes'

    key = AQCt/BpYigJ7MRAA5vy+cl39EsKpY3C+tXEGrA==

## kube user 에 대한 secret key 생성 및 조회
$ ceph auth get-or-create client.kube

## kube-node01, kube-node02 서버에 kube key 와 ceph.conf 추가
$ ssh stack@ sudo mkdir -p /etc/ceph
$ ceph auth get-or-create client.kube | ssh stack@ sudo tee /etc/ceph/ceph.client.kube.keyring
$ cat /etc/ceph/ceph.conf | ssh stack@ sudo tee /etc/ceph/ceph.conf
$ ssh stack@ sudo chown -R stack.stack /etc/ceph

$ ssh stack@ sudo mkdir -p /etc/ceph
$ ceph auth get-or-create client.kube | ssh stack@ sudo tee /etc/ceph/ceph.client.kube.keyring
$ cat /etc/ceph/ceph.conf | ssh stack@ sudo tee /etc/ceph/ceph.conf
$ ssh stack@ sudo chown -R stack.stack /etc/ceph

[ kube-node01, kube-node02 에 접속 ]
## ceph rbd client (ceph-common) 와 ceph fs client 설치 (ceph-fs-common)
$ sudo apt-get -y install ceph-common ceph-fs-common

## ceph rbd 로 연결하는 방식

## https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/rbd
## https://github.com/ceph/ceph-docker/tree/master/examples/kubernetes

[ ceph-admin 노드에서 ]

## kube keyring 파일 넣기
$ sudo vi /etc/ceph/ceph.client.kube.keyring
    key = AQCt/BpYigJ7MRAA5vy+cl39EsKpY3C+tXEGrA==

## rbd 이미지 생성
## http://karan-mj.blogspot.kr/2013/12/ceph-installation-part-3.html

$ rbd create ceph-rbd-test --pool kubes --name client.kube --size 1G -k /etc/ceph/ceph.client.kube.keyring

$ rbd list --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring
$ rbd -p kubes ls

## Jewel 의 새기능은 현재 대부분의 OS 에서 mount 문제가 있어 image 기능을 제거 해야 함
$ rbd feature disable ceph-rbd-test fast-diff --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring
$ rbd feature disable ceph-rbd-test deep-flatten --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring
$ rbd feature disable ceph-rbd-test object-map --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring
$ rbd feature disable ceph-rbd-test exclusive-lock --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring

$ rbd info ceph-rbd-test --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring
$ rbd --image ceph-rbd-test -p kubes info

$ rbd remove ceph-rbd-test --pool kubes --name client.kube -k /etc/ceph/ceph.client.kube.keyring

## secret yaml 을 만들기 위해 key 를 base64 로 인코딩 함
$ grep key /etc/ceph/ceph.client.kube.keyring |awk '{printf "%s", $NF}'|base64

[ kube-deploy 접속 ]

## secret key 를 pod 로 생성하여 접속
$ vi ~/kube/ceph-secret.yaml
apiVersion: v1
kind: Secret
  name: ceph-secret
  key: QVFDdC9CcFlpZ0o3TVJBQTV2eStjbDM5RXNLcFkzQyt0WEVHckE9PQ==

$ scp ~/kube/ceph-secret.yaml kube-master01:~/kube/.
$ ssh kube-master01 "kubectl create -f ~/kube/ceph-secret.yaml"
$ kubectl -s http://kube-master01:8080 get secrets

## rbd-with-secret pod 생성해서 rbd 활용
$ vi ~/kube/rbd-with-secret.yml
apiVersion: v1
kind: Pod
  name: rbd2
  - image: gcr.io/google_containers/busybox
    - sleep
    - "3600"
    imagePullPolicy: IfNotPresent
    name: rbd-rw-busybox
    - mountPath: "/mnt/rbd"
      name: rbdpd
  - name: rbdpd
      pool: kubes
      image: ceph-rbd-test
      user: kube
      keyring: /etc/ceph/ceph.client.kube.keyring
        name: ceph-secret
      fsType: ext4
      readOnly: false

$ scp ~/kube/rbd-with-secret.yml kube-master01:~/kube/.
$ ssh kube-master01 "kubectl create -f ~/kube/rbd-with-secret.yml"
$ kubectl -s http://kube-master01:8080 get pods

## rbd 연결 확인
$ kubectl -s http://kube-master01:8080 describe pods rbd2
$ kubectl -s http://kube-master01:8080 exec -it rbd2 -- df -h

[ kube-node02 접속하여 ]

$ docker ps
$ docker inspect --format '{{ .Mounts }}' 4c4070a1393b

## 혹은
$ mount |grep kub
/dev/rbd0 on /var/lib/kubelet/plugins/kubernetes.io/rbd/rbd/kubes-image-ceph-rbd-test type ext4 (rw,relatime,stripe=1024,data=ordered)
/dev/rbd0 on /var/lib/kubelet/pods/061973fc-a265-11e6-940f-5cb9018c67dc/volumes/kubernetes.io~rbd/rbdpd type ext4 (rw,relatime,stripe=1024,data=ordered)

[ kube-deploy 접속해서 ]

## secret key pod 를 사용하지 않고 keyring 으로만 rbd pod 생성
$ vi ~/kube/rbd.yml
apiVersion: v1
kind: Pod
  name: rbd
  - image: gcr.io/google_containers/busybox
    - sleep
    - "3600"
    imagePullPolicy: IfNotPresent
    name: rbd-rw-busybox
    - mountPath: "/mnt/rbd"
      name: rbdpd
  - name: rbdpd
      pool: kubes
      image: ceph-rbd-test
      user: kube
      keyring: /etc/ceph/ceph.client.kube.keyring
      fsType: ext4
      readOnly: false

$ scp ~/kube/rbd.yml kube-master01:~/kube/.
$ ssh kube-master01 "kubectl create -f ~/kube/rbd.yml"
$ kubectl -s http://kube-master01:8080 get pods

## rbd 연결 확인

$ kubectl -s http://kube-master01:8080 exec -it rbd -- df -h 

저작자 표시 변경 금지
Posted by Kubernetes Korea co-leader seungkyua@gmail.com